一、条件变量

  条件变量实现了java.util.concurrent.locks.Condition接口,条件变量的实例化就是通过一个Lock对象上调用newCondition()方法获得的,这样条件就和一个锁绑定起来了。因此,Java中的条件变量只能和锁配合使用,来控制并发程序访问竞争资源的安全。

  条件变量的出现是为了更精细的控制线程等待与唤醒,一个锁可以有多个条件,每个条件上有多个线程等待,通过await()方法,可以让线程在该条件下等待。当调用signalAll()方法时,又可以唤醒该条件下等待的线程。条件变量比较抽象,原因是它不是自然语言中的条件概念,而是控制程序的一种手段。

  看个例子,有一个账户,多个用户(线程)在同时操作这个账户,有的存款有的取款,存款随便存,但取款有限制,不能透支,任何试图透支的操作都将等待里面有足够的存款时才执行操作。

  CaseTest.java

 1 package Thread;
 2 import java.util.*;
 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 public class CaseTest {
 9     public static void main(String[] args){
10         MyCount1 myCount1=new MyCount1("6516431",10000);
11         ExecutorService pool=Executors.newFixedThreadPool(2);
12         Thread t1=new SaveThread("张三",myCount1,2000);
13         Thread t2=new DrawThread("李四",myCount1,3600);
14         Thread t3=new SaveThread("王二",myCount1,2700);
15         Thread t4=new SaveThread("麻子",myCount1,600);
16         Thread t5=new DrawThread("胖子",myCount1,1300);
17         Thread t6=new DrawThread("小刘",myCount1,800);
18         pool.execute(t1);
19         pool.execute(t2);
20         pool.execute(t3);
21         pool.execute(t4);
22         pool.execute(t5);
23         pool.execute(t6);
24         pool.shutdown();
25     }
26 }
27 class SaveThread extends Thread{
28     private String name;
29     private MyCount1 myCount1;
30     private int x;
31     SaveThread(String name,MyCount1 myCount1,int x){
32         this.name=name;
33         this.myCount1=myCount1;
34         this.x=x;
35     }
36     public void run(){
37         myCount1.saving(x,name);
38     }
39 }
40 class DrawThread extends Thread{
41     private String name;
42     private MyCount1 myCount;
43     private int x;
44     DrawThread(String name,MyCount1 myCount,int x){
45         this.name=name;
46         this.myCount=myCount;
47         this.x=x;
48     }
49     public void run(){
50         myCount.drawing(x,name);
51     }
52 }
53 class MyCount1{
54     private String oid;
55     private int cash;
56     private Lock lock=new ReentrantLock();
57     private Condition _save=lock.newCondition();
58     private Condition _draw=lock.newCondition();
59     MyCount1(String oid,int cash){
60         this.oid=oid;
61         this.cash=cash;
62     }
63     public void saving(int x,String name){
64         lock.lock(); //获取锁 
65         if(x>0){
66             cash+=x;
67             System.out.println(name+"存款"+x+",当前余额为:"+cash);
68         }
69         _draw.signalAll(); //唤醒所有等待线程。 
70         lock.unlock(); //释放锁 
71     }
72     public void drawing(int x,String name){
73         lock.lock();
74         try{
75             if(cash-x<0){
76                 _draw.await();//阻塞取款操作
77             }else{    
78                 cash-=x;
79                 System.out.println(name+"取款"+x+",当前余额为:"+cash);
80             }
81             _save.signalAll();//唤醒所有存款操作
82         }catch(InterruptedException e){
83             e.printStackTrace();
84         }finally{
85             lock.unlock();
86         }
87     }
88 }
View Code

相关文章: