Lock&Condition实现线程同步通信

Definition

Condition的功能类似于传统线程技术中的Object.wait和Object.notify的功能。

一个锁内部可以有多个Condition,即有多路等待和通知。

在传统的线程机制中一个监视器对象只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。

Example

多路等待示例:

1、模板代码

 class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   }
 }

2、实例代码

 1 public class ConditionCommunication {
 2 
 3     public static void main(String[] args) {
 4 
 5         final Business business = new Business();
 6         new Thread(
 7                 new Runnable(){
 8                         public void run(){
 9                             for(int i=1;i<=10;i++){
10                                 business.sub(i);
11                             }
12                         }
13                     }
14                 ).start();
15 
16         for(int i=1;i<=50;i++){
17             business.main(i);
18         }
19     }
20     
21     static class Business {
22         Lock lock = new ReentrantLock();
23         Condition condition = lock.newCondition();
24         private boolean bShouldSub = true;
25         
26         public void sub(int i){
27             lock.lock();
28             try{
29                 while(!bShouldSub){//while用于防止虚假唤醒
30                     try {
31                         condition.await();
32                     } catch (Exception e) {
33                         // TODO Auto-generated catch block
34                         e.printStackTrace();
35                     }
36                 }
37                 for(int j=1;j<=10;j++){
38                     System.out.println("sub thread sequece of " + j + ",loop of " + i);
39                 }
40                 bShouldSub = false;
41                 condition.signal();
42             }finally{
43                 lock.unlock();
44             }
45         }
46         
47         public void main(int i){
48             lock.lock();
49             try{
50                 while(bShouldSub){
51                     try {
52                         condition.await();
53                     } catch (Exception e) {
54                         // TODO Auto-generated catch block
55                         e.printStackTrace();
56                     }
57                 }
58                 for(int j=1;j<=100;j++){
59                         System.out.println("main thread sequece of " + j + ",loop of " + i);
60                     }
61                 bShouldSub = true;
62                 condition.signal();
63             }finally{
64                 lock.unlock();
65             }
66         }
67     }
68 }

3、3线程交互示例:

本例中包含3个线程,main、sub2和sub3,3个线程交替执行先是main然后是sub2,sub2又交给sub3,sub3再交给main,如此循环往复执行50次。

  1 public class ThreeConditionCommunication {
  2 
  3     public static void main(String[] args) {
  4 
  5         final Business business = new Business();
  6         new Thread(
  7                 new Runnable(){
  8                         public void run(){
  9                             for(int i=1;i<=50;i++){
 10                                 business.sub2(i);
 11                             }
 12                         }
 13                     }
 14                 ).start();
 15         
 16         new Thread(
 17                 new Runnable(){
 18                         public void run(){
 19                             for(int i=1;i<=50;i++){
 20                                 business.sub3(i);
 21                             }
 22                         }
 23                     }
 24                 ).start();
 25 
 26         for(int i=1;i<=50;i++){
 27             business.main(i);
 28         }
 29     }
 30     
 31     static class Business {
 32         Lock lock = new ReentrantLock();
 33         //Condition定义
 34         Condition condition1 = lock.newCondition();
 35         Condition condition2 = lock.newCondition();
 36         Condition condition3 = lock.newCondition();
 37         private int ShouldSub = 1;
 38         
 39         public void sub2(int i){
 40             lock.lock();
 41             try{
 42                 //while用于防止虚假唤醒,很重要
 43                 while(ShouldSub != 2){
 44                     try {
 45                         condition2.await();
 46                     } catch (Exception e) {
 47                         // TODO Auto-generated catch block
 48                         e.printStackTrace();
 49                     }
 50                 }
 51                 for(int j=1;j<=10;j++){
 52                     System.out.println("sub2 thread sequece of " + j + ",loop of " + i);
 53                 }
 54                 ShouldSub = 3;
 55                 condition3.signal();
 56             }finally{
 57                 lock.unlock();
 58             }
 59         }
 60         
 61         public void sub3(int i){
 62             lock.lock();
 63             try{
 64                 while(ShouldSub != 3){
 65                     try {
 66                         condition3.await();
 67                     } catch (Exception e) {
 68                         // TODO Auto-generated catch block
 69                         e.printStackTrace();
 70                     }
 71                 }
 72                 for(int j=1;j<=20;j++){
 73                     System.out.println("sub3 thread sequece of " + j + ",loop of " + i);
 74                 }
 75                 ShouldSub = 1;
 76                 condition1.signal();
 77             }finally{
 78                 lock.unlock();
 79             }
 80         }
 81         
 82         public void main(int i){
 83             lock.lock();
 84             try{
 85                 while(ShouldSub != 1){
 86                     try {
 87                         condition1.await();
 88                     } catch (Exception e) {
 89                         // TODO Auto-generated catch block
 90                         e.printStackTrace();
 91                     }
 92                 }
 93                 for(int j=1;j<=100;j++){
 94                     System.out.println("main thread sequece of " + j + ",loop of " + i);
 95                 }
 96                 ShouldSub = 2;
 97                 condition2.signal();
 98             }finally{
 99                 lock.unlock();
100             }
101         }
102     }
103 }

部分运行结果:

main thread sequece of 94,loop of 34
main thread sequece of 95,loop of 34
main thread sequece of 96,loop of 34
main thread sequece of 97,loop of 34
main thread sequece of 98,loop of 34
main thread sequece of 99,loop of 34
main thread sequece of 100,loop of 34
sub2 thread sequece of 1,loop of 34
sub2 thread sequece of 2,loop of 34
sub2 thread sequece of 3,loop of 34
sub2 thread sequece of 4,loop of 34
sub2 thread sequece of 5,loop of 34
sub2 thread sequece of 6,loop of 34
sub2 thread sequece of 7,loop of 34
sub2 thread sequece of 8,loop of 34
sub2 thread sequece of 9,loop of 34
sub2 thread sequece of 10,loop of 34
sub3 thread sequece of 1,loop of 34
sub3 thread sequece of 2,loop of 34
sub3 thread sequece of 3,loop of 34
原文地址:https://www.cnblogs.com/shen-smile/p/5145645.html