终于弄懂了晦涩难懂的条件锁-condition lock

来源:互联网 发布:知乎live过期收听购买 编辑:程序博客网 时间:2024/06/06 16:37
[java] view plain copy
  1. package com.cn.whu;  
  2.   
  3. import java.util.concurrent.ExecutorService;  
  4. import java.util.concurrent.Executors;  
  5. import java.util.concurrent.locks.Condition;  
  6. import java.util.concurrent.locks.Lock;  
  7. import java.util.concurrent.locks.ReentrantLock;  
  8.   
  9. public class ThreadConditionLook {  
  10.   
  11.     /** 
  12.      * @param args 
  13.      */  
  14.     //create a user's Account,watch out the "static"  
  15.     private static Account account = new Account();  
  16.     public static void main(String[] args) {  
  17.         // TODO Auto-generated method stub  
  18.         ExecutorService executor = Executors.newFixedThreadPool(2);  
  19.         executor.execute(new DepositTask());  
  20.         executor.execute(new WithdrawTask());  
  21.         executor.shutdown();  
  22.         System.out.println("Thread 1\t\tThread 2\t\t\t\tBalance");  
  23.     }  
  24.     private static class Account{  
  25.         //create a new lock  
  26.         private static Lock lock = new ReentrantLock();  
  27.         //craete a condition  
  28.         private static Condition newDeposit = lock.newCondition();  
  29.         private int  balance =0;  
  30.         public int getBalance(){  
  31.             return balance;  
  32.         }  
  33.         public void withdraw(int mount){  
  34.             lock.lock();//Acqurie the lock  
  35.             try{  
  36.                 while(balance<mount){  
  37.                     System.out.println("\t\t\tWait for a deposit");  
  38.                     newDeposit.await();  
  39.                 }  
  40.                 balance -=mount;   
  41.                 System.out.println("\t\t\tWithdraw "+mount+"\t\t\t\t\t"+getBalance());  
  42.             }catch(InterruptedException e){  
  43.                   
  44.             }finally{  
  45.                 lock.unlock();  
  46.             }  
  47.         }  
  48.         public void depsoit(int mount){  
  49.             lock.lock();  
  50.             try{  
  51.                 balance+=mount;  
  52.                 System.out.println("Deposit "+mount+"\t\t\t\t\t\t\t\t"+getBalance());  
  53.                 newDeposit.signalAll();  
  54.             }finally{  
  55.                 lock.unlock();  
  56.             }  
  57.         }  
  58.     }  
  59.     //Task for deposit account;  
  60.     private static class DepositTask implements Runnable{  
  61.   
  62.         @Override  
  63.         public void run() {  
  64.             // TODO Auto-generated method stub  
  65.               
  66.             try{  
  67.                 while(true){  
  68.                     account.depsoit((int)(Math.random()*10)+1);  
  69.                     Thread.sleep(1000);  
  70.                 }  
  71.                   
  72.             }catch(InterruptedException e){  
  73.                   
  74.             }  
  75.               
  76.               
  77.         }  
  78.           
  79.     }  
  80.     //Task for withdraw account  
  81.     private static class WithdrawTask implements Runnable{  
  82.   
  83.         @Override  
  84.         public void run() {  
  85.             // TODO Auto-generated method stub  
  86.             try{  
  87.                 while(true){  
  88.                     account.withdraw((int)(Math.random()*10)+1);  
  89.                     Thread.sleep(1000);  
  90.                 }  
  91.             }catch(InterruptedException e){  
  92.                   
  93.             }  
  94.         }  
  95.           
  96.     }  
  97. }  


条件锁其实就是一个普通的锁加上了一个条件,如下面两行代码

//create a new lockprivate static Lock lock = new ReentrantLock();

//craete a conditionprivate static Condition newDeposit = lock.newCondition();

,重要的不是表象,是为什么需要这个条件锁,假设你有一个银行账户,密码你和你老婆都知道,你负责存钱,你老婆负责取钱,对存钱和取钱的代码都加了锁,所以是可以同步的。诶,平常存啊取的都挺好的,结果你俩矛盾了,你不去存钱,诶银行发现你老婆仍然可以取,而且透支了,你愿意不?银行愿意不?当然不愿意,也许你马上想到了,诶,我可以在取钱的时候加个条件去判断下,如果够取,那就让这个线程来取钱,否则呢?关键是这个否则呢?把这个线程干掉?不人道吧,让人家自己过N年后来取?这也不人道啊,评啥不是你通知人家老公存钱了,老婆过来看看,看够取不?诶,这个条件锁他就是这个为别人考虑的东西,你老婆一旦发现钱不够取了,他就打电话给你,嘿,小伙子,快点存钱,你说我有事,等会在存,等了很久,你存了一点,好,你在打电话给她,说,你可以去取取看,看过不,不够在打电话给我,够了直接取了就是。

微笑



我觉你的那个比喻不恰当,特别是这句话:“老婆一旦发现钱不够取了,他就打电话给你,嘿,小伙子,快点存钱,你说我有事,等会在存,等了很久,你存了一点,好,你在打电话给她,说,你可以去取取看,看过不,不够在打电话给我,够了直接取了就是。“
其实就是生产者和消费者问题嘛,取钱的线程发现钱不够就会阻塞,存钱的线程是一直在执行的,一旦存了钱,他便会唤醒取钱的线程。也就是说,他老婆发现钱不够了,并不会打电话给他老公,而是等待她老公去存钱,她老公存了钱,会通知他老婆去取才对。

0 0
原创粉丝点击