lock+Condition

关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象。Condition类是JDK5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能,选择性的进行线程通知,在调度线程上更加灵活。

使用wait+notify/notifyAll方法进行通知时,被通知的线程却是由JVM随机选择的。但使用reentrantLock结合Condition类是可以实现选择性通知。

Object类中的wait()方法,相当于Condition类中的await()方法;Object类中的notify()方法,相当于Condition类中的signal()方法。Object类中的notifyAll方法,相当于Condition类中的signalAll()方法。

 打印 12A34B.......5152Z

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.Lock;
 3 import java.util.concurrent.locks.ReentrantLock;
 4 
 5 public class Print12A_RC {
 6     
 7     private Lock lock =new ReentrantLock();
 8     private Condition con=lock.newCondition();
 9     private boolean isInt=true;
10     private int i=1;
11     private char ch ='A';
12     public void printInt()
13     {
14         try {
15             lock.lock();
16             while(!isInt)
17             {
18                 con.await();
19             }
20             System.out.print((i++)+""+(i++));
21             isInt=false;
22             con.signal();
23         } catch (Exception e) {
24         }
25         finally
26         {
27             lock.unlock();
28         }
29     }
30     
31     public void printChar()
32     {
33         try {
34             lock.lock();
35             while(isInt)
36             {
37                 con.await();
38             }
39             System.out.print((char)ch);
40             ch++;
41             isInt=true;
42             con.signal();
43             
44             
45         } catch (Exception e) {
46         }
47         finally {
48             lock.unlock();
49         }
50     }
51     
52     public static void main(String[] args) {
53         Print12A_RC rc=new Print12A_RC();
54         Thread aThread=new Thread(new Runnable() {
55             
56             @Override
57             public void run() {
58                 for(int i=0;i<26;i++)
59                 {
60                     rc.printInt();
61                 }
62             }
63         });
64         Thread bThread =new Thread(new Runnable() {
65             
66             @Override
67             public void run() {
68                 for(int i=0;i<26;i++)
69                 {
70                     rc.printChar();
71                 }
72             }
73         });
74         aThread.start();
75         bThread.start();
76     }
77 }

 顺序打印,如123123123....

  1 package multiMethod.reentrantLockCondition;
  2 
  3 import java.util.concurrent.locks.Condition;
  4 import java.util.concurrent.locks.ReentrantLock;
  5 
  6 public class PrintByOrder {
  7     ReentrantLock lock =new ReentrantLock();
  8     Condition condition=lock.newCondition();
  9     int printnext=1;
 10     
 11     public void print1()
 12     {
 13         lock.lock();
 14         try{
 15             while(printnext!=1)
 16             {
 17                 condition.await();
 18             }
 19             Thread.sleep(500);//不加此行会不打印,不知什么原因。
 20             System.out.print(1);
 21             printnext=2;
 22             condition.signalAll();
 23         }
 24         catch (Exception e) {
 25             // TODO: handle exception
 26         }
 27         finally{
 28             lock.unlock();
 29         }
 30     }
 31     
 32     public void print2()
 33     {
 34         lock.lock();
 35         try{
 36             while(printnext!=2)
 37             {
 38                 condition.await();
 39             }
 40             System.out.print(2);
 41             printnext=3;
 42             condition.signalAll();
 43         }
 44         catch (Exception e) {
 45         }
 46         finally{
 47             lock.unlock();
 48         }
 49     }
 50     
 51     public void print3()
 52     {
 53         lock.lock();
 54         try{
 55             while(printnext!=3)
 56             {
 57                 condition.await();
 58             }
 59             System.out.print(3);
 60             printnext=1;
 61             condition.signalAll();
 62         }
 63         catch (Exception e) {
 64             // TODO: handle exception
 65         }
 66         finally{
 67             lock.unlock();
 68         }
 69     }
 70 
 71     public static void main(String[] args) {
 72         PrintByOrder order=new PrintByOrder();
 73         Runnable runnable1=new Runnable() {
 74             
 75             @Override
 76             public void run() {
 77                 while(true){
 78                     order.print1();
 79                 }
 80             }
 81         };
 82         
 83         Runnable runnable2=new Runnable() {
 84             
 85             @Override
 86             public void run() {
 87                 while(true){
 88                     order.print2();
 89                 }
 90             }
 91         };
 92         
 93         Runnable runnable3=new Runnable() {
 94             
 95             @Override
 96             public void run() {
 97                 while(true){
 98                     order.print3();
 99                 }
100             }
101         };
102         
103         new Thread(runnable1).start();
104         new Thread(runnable2).start();
105         new Thread(runnable3).start();
106     }
107 }

 

读写锁,比上面的lock+condition提高效率。

 

ReentrantReadWriteLock会使用两把锁来解决问题,一个读锁,一个写锁
线程进入读锁的前提条件:
    没有其他线程的写锁,
    没有写请求或者有写请求,但调用线程和持有锁的线程是同一个

线程进入写锁的前提条件:
    没有其他线程的读锁
    没有其他线程的写锁

简单来说,就是读读共享,写写互斥,读写互斥。

另外,ReentrantReadWriteLock.readLock 无需newCondition,而ReentrantReadWriteLock.writeLock可以newCondition,用于多个读线程之间的通信。

 

 1 import java.util.concurrent.locks.ReentrantReadWriteLock;
 2 
 3 public class ReadWriteLock {
 4     private ReentrantReadWriteLock rw= new ReentrantReadWriteLock();
 5     
 6     public void readLock(){
 7         
 8         
 9         try {
10             rw.readLock().lock();
11             System.out.println("read before sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
12             Thread.sleep(2000);
13             System.out.println("read after sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
14         } catch (Exception e) {
15             // TODO: handle exception
16         }finally{
17             rw.readLock().unlock();
18         }
19     }
20     
21     public void writeLock(){
22         
23         
24         try {
25             rw.writeLock().lock();
26             System.out.println("write before sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
27             Thread.sleep(2000);
28             System.out.println("write after sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
29         } catch (Exception e) {
30             // TODO: handle exception
31         }finally{
32             rw.writeLock().unlock();
33         }
34     }
35     
36     public static void main(String[] args) {
37         ReadWriteLock rwl=new ReadWriteLock();
38         Runnable runnable=new Runnable() {
39             
40             @Override
41             public void run() {
42                 rwl.writeLock();
43                 rwl.readLock();
44 
45             }
46         };
47         Thread[] threads=new Thread[10];
48         for(int i=0;i<5;i++)
49         {
50             threads[i]=new Thread(runnable);
51         }
52         for(int i=0;i<5;i++)
53         {
54             threads[i].start();
55         }
56     }
57 
58 }

 

转载于:https://www.cnblogs.com/wfq9330/p/8708290.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值