Account类
package com.thread.communication.condition; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Account2 { private final Lock lock = new ReentrantLock(); private final Condition conddraw = lock.newCondition(); private final Condition conddeposit = lock.newCondition(); private String accountNo; private double balance; private boolean flag = false; public Account2(){} public Account2(String accountNo , double balance){ this.accountNo=accountNo; this.balance=balance; } public void setAccountNo(String num){ this.accountNo=num; } public String getAccountNo(){ return this.accountNo; } public double getBalance(){ return this.balance; } public void draw(double drawAmount){ System.out.println("drawtest"); lock.lock(); try{ System.out.println("开始取钱"); if(!flag){ System.out.println(Thread.currentThread().getName() + "被阻塞 "); conddraw.await(); //conddraw.await(1000,TimeUnit.MILLISECONDS); }else{ System.out.println(Thread.currentThread().getName() + "取钱: " + drawAmount); this.balance-=drawAmount; System.out.println("当前余额是: "+ balance); flag = false; conddeposit.signalAll(); System.out.println("通知存钱者 "); } }catch(InterruptedException ex){ ex.printStackTrace(); }finally{ lock.unlock(); } } public void deposit(double depositAmount){ System.out.println("deposittest"); lock.lock(); try{ System.out.println("开始存钱"); if(flag){ System.out.println(Thread.currentThread().getName() + "被阻塞 "); conddeposit.await(); //conddeposit.await(1000,TimeUnit.MILLISECONDS); }else{ System.out.println(Thread.currentThread().getName() + "存钱: " + depositAmount); this.balance+=depositAmount; System.out.println("当前余额是: "+ balance); flag = true; conddraw.signalAll(); System.out.println("通知取钱者 "); } }catch(InterruptedException ex){ ex.printStackTrace(); }finally{ lock.unlock(); } } public int hashCode(){ return accountNo.hashCode(); } public boolean equals(Object obj){ if(this == obj) return true; if(obj !=null && obj.getClass()==Account2.class){ Account2 target =(Account2)obj; return target.getAccountNo().equals(accountNo); } return false; } }
两个线程
package com.thread.communication.condition; public class DepositThread2 extends Thread{ private Account2 account2; private double depositAmount; private String name; public DepositThread2(String name,Account2 account2,double depositAmount){ super(name); this.name=name; this.account2=account2; this.depositAmount=depositAmount; } public void run(){ for (int i=0;i<30;i++){ System.out.println(name + "第"+i+"次存钱"); account2.deposit(depositAmount); } } }
package com.thread.communication.condition; public class DrawThread2 extends Thread{ private Account2 account2; private double drawAmount; private String name; public DrawThread2(String name,Account2 account2,double drawAmount){ super(name); this.name=name; this.account2=account2; this.drawAmount=drawAmount; } public void run(){ for (int i=0;i<30;i++){ System.out.println(name+"第"+i+"次取钱"); account2.draw(drawAmount); } } }
测试类
package com.thread.communication.condition; public class DrawTest2 { public static void main(String[] args) { Account2 acct = new Account2("account2",0.0); System.out.println(acct.getAccountNo() + " " + acct.getBalance()); new DepositThread2("存钱者甲",acct,800.0).start(); new DepositThread2("存钱者已",acct,800.0).start(); new DepositThread2("存钱者丙",acct,800.0).start(); new DrawThread2("取钱者",acct,800.0).start(); } }
运行结果
account2 0.0 存钱者甲第0次存钱 存钱者已第0次存钱 deposittest deposittest 开始存钱 存钱者丙第0次存钱 deposittest 取钱者第0次取钱 drawtest 存钱者已存钱: 800.0 当前余额是: 800.0 通知取钱者 。。。 deposittest 开始存钱 存钱者甲存钱: 800.0 当前余额是: 800.0 通知取钱者 存钱者丙第15次存钱 deposittest 开始存钱 存钱者丙被阻塞 存钱者已第18次存钱 deposittest 开始存钱 存钱者已被阻塞