java并发控制:ReentrantLock Condition使用详解

http://my.oschina.net/004/blog/467286

我们通过一个实际的例子来解释Condition的用法:

我们要打印1到9这9个数字,由A线程先打印1,2,3,然后由B线程打印4,5,6,然后再由A线程打印7,8,9. 这道题有很多种解法,现在我们使用Condition来做这道题(使用Object的wait,notify方法的解法在这里 http://outofmemory.cn/java/java.util.concurrent/thread-sync-with-object-wait-notify-notifyAll)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package cn.xband.locks;
 
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
public class Test{
     static class NumberWrapper {
         public int value = 1 ;
     }
 
     public static void main(String[] args) {
         //初始化可重入锁
         final Lock lock = new ReentrantLock();
         
         //第一个条件当屏幕上输出到3
         final Condition reachThreeCondition = lock.newCondition();
         //第二个条件当屏幕上输出到6
         final Condition reachSixCondition = lock.newCondition();
         
         //NumberWrapper只是为了封装一个数字,一边可以将数字对象共享,并可以设置为final
         //注意这里不要用Integer, Integer 是不可变对象
         final NumberWrapper num = new NumberWrapper();
         //初始化A线程
         Thread threadA = new Thread( new Runnable() {
             @Override
             public void run() {
                 //需要先获得锁
                 lock.lock();
                 try {
                     System.out.println( "threadA start write" );
                     //A线程先输出前3个数
                     while (num.value <= 3 ) {
                         System.out.println(num.value);
                         num.value++;
                     }
                     //输出到3时要signal,告诉B线程可以开始了
                     reachThreeCondition.signal();
                 } finally {
                     lock.unlock();
                 }
                 lock.lock();
                 try {
                     //等待输出6的条件
                     reachSixCondition.await();
                     System.out.println( "threadA start write" );
                     //输出剩余数字
                     while (num.value <= 9 ) {
                         System.out.println(num.value);
                         num.value++;
                     }
 
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 } finally {
                     lock.unlock();
                 }
             }
 
         });
 
 
         Thread threadB = new Thread( new Runnable() {
             @Override
             public void run() {
                 try {
                     lock.lock();
                     
                     while (num.value <= 3 ) {
                         //等待3输出完毕的信号
                         reachThreeCondition.await();
                     }
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 } finally {
                     lock.unlock();
                 }
                 try {
                     lock.lock();
                     //已经收到信号,开始输出4,5,6
                     System.out.println( "threadB start write" );
                     while (num.value <= 6 ) {
                         System.out.println(num.value);
                         num.value++;
                     }
                     //4,5,6输出完毕,告诉A线程6输出完了
                     reachSixCondition.signal();
                 } finally {
                     lock.unlock();
                 }
             }
 
         });
 
 
         //启动两个线程
         threadB.start();
         threadA.start();
     }
}



上述代码中有完整的注释,请参考注释,理解Condition的用法。

基本思路就是首先要A线程先写1,2,3,这时候B线程应该等待reachThredCondition信号,而当A线程写完3之后就通过signal告诉B线程“我写到3了,该你了”,这时候A线程要等嗲reachSixCondition信号,同时B线程得到通知,开始写4,5,6,写完4,5,6之后B线程通知A线程reachSixCondition条件成立了,这时候A线程就开始写剩下的7,8,9了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值