这里还是经典的账户存取钱的问题,因为在学习线程的通信,学习了java的lock机制,试着自己用lock的await()、signalAll()、signalAll()重现了一下synchronized的wait、notify、notifyAll的机制,算是加深印象吧
要实现的逻辑是先存钱,再取钱,再存再取的执行顺序
这是账户类:经典的模型,还是这样,里面有存取和取钱方法
1 package treadTest.notify; 2 3 import java.util.concurrent.locks.Condition; 4 import java.util.concurrent.locks.ReentrantLock; 5 6 public class Account { 7 private String age; 8 private double count; 9 10 11 private ReentrantLock lock = new ReentrantLock(); 12 private Condition condition = lock.newCondition(); 13 14 15 16 17 private boolean flag = false; //true有存 false没存 18 19 public Account(String age, double count) { 20 this.age = age; 21 this.count = count; 22 } 23 24 public String getAge() { 25 return age; 26 } 27 public void setAge(String age) { 28 this.age = age; 29 } 30 public double getCount() { 31 return count; 32 } 33 public void setCount(double count) { 34 this.count = count; 35 } 36 37 38 39 public void draw(double drawCount,int num){ 40 lock.lock(); 41 try { 42 if(!flag){//没钱 43 condition.await(); //类似于synchised 的wait()方法 44 System.out.println(Thread.currentThread().getName() + "第"+num+"次取钱 没钱在等待"); 45 } 46 if(this.count>=drawCount){ 47 System.out.println(Thread.currentThread().getName() + "第"+num+"次取钱"+drawCount+"元"); 48 this.setCount(this.count-drawCount); 49 System.out.println("剩余"+count); 50 flag=false; 51 condition.signalAll(); 52 53 } 54 else{ 55 System.out.println("余额不足!"); 56 } 57 } catch (Exception e) { 58 }finally{ 59 lock.unlock(); 60 } 61 } 62 63 public void deposit(double depositCount,int num){ 64 lock.lock(); 65 try { 66 if(flag){//有钱 67 condition.await(); //类似于synchised 的wait()方法 68 System.out.println(Thread.currentThread().getName() + "第"+num+"次存钱 有钱在等待"); 69 } 70 System.out.println(Thread.currentThread().getName() + "第"+num+"次存入了"+depositCount+"元"); 71 this.setCount(this.count+depositCount); 72 System.out.println("剩余"+count); 73 flag=true; 74 condition.signalAll();//类似于synchised 的notify()方法 75 } catch (Exception e) { 76 }finally{ 77 lock.unlock(); 78 } 79 80 }
存钱线程类,专门负责存钱
1 package treadTest.notify; 2 3 public class Deposit extends Thread{ 4 private Account account; 5 6 public Deposit(Account account) { 7 this.account = account; 8 } 9 10 11 @Override 12 public void run() { 13 for(int i=0;i<100;i++){ 14 account.deposit(100.0,i+1); 15 } 16 } 17 18 }
取钱多线程类:负责取钱
1 package treadTest.notify; 2 3 public class Draw extends Thread{ 4 private Account account; 5 6 public Draw(Account account) { 7 this.account = account; 8 } 9 10 11 @Override 12 public void run() { 13 for(int i=0;i<100;i++){ 14 account.draw(90.0,i+1); 15 } 16 } 17 }
存取钱测试类:
1 package treadTest.notify; 2 3 public class AccountTest { 4 5 6 public static void main(String[] args) { 7 Account account = new Account("lina", 0.0); 8 new Deposit(account).start(); 9 new Draw(account).start(); 10 } 11 12 }打印的结果如下:
Thread-0第1次存入了100.0元
剩余100.0
Thread-1第1次取钱90.0元
剩余10.0
Thread-0第2次存钱 有钱在等待
Thread-0第2次存入了100.0元
剩余110.0
Thread-1第2次取钱90.0元…………………………………………
剩余990.0
Thread-0第100次存钱 有钱在等待
Thread-0第100次存入了100.0元
剩余1090.0
Thread-1第100次取钱 没钱在等待
Thread-1第100次取钱90.0元
剩余1000.0