线程同步:银行帐户存、取款问题
2014-11-30 21:05
288 查看
1.银行账户类
2.存款线程
3.取款线程
结果:
package com.bankAccount.test; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Account { //显式定义Lock对象 private final Lock lock=new ReentrantLock(); //获得指定Lock对象对应的Condition private final Condition cond=lock.newCondition(); //封装账户编号,账户余额的两个成员变量 private String accoutNo; private double balance; //标识账户中是否已有存款的旗标 private boolean flag=false; public Account(){} //构造器 public Account(String accountNo,double balance) { this.accoutNo=accountNo; this.balance=balance; } public String getAccoutNo() { return accoutNo; } public void setAccoutNo(String accoutNo) { this.accoutNo = accoutNo; } //因为账户余额不可以随便修改,所以只为balance提供getter方法 public double getBalance() { return this.balance; } public void draw(double drawAmount) { //加锁 lock.lock(); try{ if(!flag) { cond.await(); } else { //执行取钱操作 System.out.println(Thread.currentThread().getName()+ "取钱:"+drawAmount); balance-=drawAmount; System.out.println("账户余额为:"+balance); //将标识账户是否已有存款的旗标设为false flag=false; //唤醒其他进程 cond.signalAll(); } } catch(InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } public void deposit(double depositAmount) { lock.lock(); try{ //如果flag为真,表明账户中已经有人存钱进去,存钱方法阻塞 if(flag) { cond.await(); } else { //执行存款操作 System.out.println(Thread.currentThread().getName()+ "存款:"+depositAmount); balance+=depositAmount; System.out.println("账户余额为:"+balance); //将表示是否已有存款的旗标设为true flag=true; //唤醒其他线程 cond.signalAll(); } } catch(InterruptedException ex) { ex.printStackTrace(); } finally{ lock.unlock(); } } public int hashCode() { return accoutNo.hashCode(); } public boolean equals(Object obj) { if(this==obj) return true; if(obj!=null&&obj.getClass()==Account.class) { Account target=(Account)obj; return target.getAccoutNo().equals(accoutNo); } return false; } }
2.存款线程
package com.bankAccount.test; public class DepositThread extends Thread{ private Account account; //当前存款线程所希望存的钱数 private double depositAmount; public DepositThread(String name,Account account, double depositAmount) { super(name); this.account=account; this.depositAmount=depositAmount; } public void run() { for(int i=0;i<100;i++) { account.deposit(depositAmount); } } }
3.取款线程
package com.bankAccount.test; public class DrawThread extends Thread{ //模拟用户账户 private Account account; //当前取钱线程所希望取的钱数 private double drawAmount; public DrawThread(String name,Account account,double drawAmount) { super(name); this.account=account; this.drawAmount=drawAmount; } //当多个线程修改同一个共享数据时,将涉及数据安全问题 public void run() { //使用account作为同步监视器,任何线程进入下面同步代码块之前 //必须先获得对account账户的锁定---其他线程无法获得锁,也就无法修改它 //该做法符合:"加锁->修改->释放锁" for(int i=0;i<100;i++) { account.draw(drawAmount); } } }4.测试类
package com.bankAccount.test; public class DrawTest { public static void main(String[] args) { //创建一个账户 Account acct=new Account("123",0); //模拟两个线程对同一个账户取 钱 new DrawThread("取钱者",acct,800).start(); new DepositThread("存款者甲",acct,800).start(); new DepositThread("存款者乙",acct,800).start(); new DepositThread("存款者丙",acct,800).start(); } }
结果:
相关文章推荐
- java 银行存取款模型的线程同步问题
- java 线程同步问题之银行存取款问题
- 解决在创建银行帐户,输入帐户拥有人时找不到法人实体的问题
- 解决在创建银行帐户,输入帐户拥有人时找不到法人实体的问题
- java学习7:银行存取款的例子,主要涉及对象同步问题,类似于数据库存取款,数据一致性问题
- 用JAVA中的多线程示例银行取款问题
- c#04-02编写异常处理,实现银行存取款过程中可能遇到的问题
- 2.为方便储户,某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员键入系统,如果是存款,系统记录存款人姓名、住址、存款类型、存款日期、利率等信息,并印出存款单给储户;如果是取款,系统计算利息并印出利息清单给储户。 请写出问题定义并分析此系统的可行性。
- java面试题-用JAVA中的多线程示例银行取款问题
- 银行取款[多线程]{使用同步方法确保线程同步}
- 银行取款[多线程]{未进行线程同步}(junit不适合多线程并发单元测试)
- 银行取款[多线程]{使用ThreadLocal管理共享变量,但此场景并不保证线程同步}
- (转)解决在创建银行帐户,输入帐户拥有人时找不到法人实体的问题
- 银行取款[多线程]{使用重入锁Lock接口ReentrantLock锁确保线程同步}
- 为方便储户,某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员输入系统,如果是存款,系统记录存款人姓名、住址、存款类型、存款日期、利率等信息,并印出存款单给储户;如果是取款,系统计算利息并印出利息清单给储户。 写出问题定义并分析系统的可行性。
- 2-2 为方便储户,某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员键入系统,如果是存款,系统记录存款人姓名、住址、存款类型、存款日期、利率等信息,并印出存款单给储户;如果是取款,系统计算利息并印出利息清单给储户。请写出问题定义并分析此系统的可行性。
- 用JAVA中的多线程示例银行取款问题
- 银行取款[多线程]{使用volatile修饰共享变量,但此场景并不保证线程同步}
- 用JAVA的多线程实现银行取款的问题
- java面试题-用JAVA中的多线程示例银行取款问题标准版