码迷,mamicode.com
首页 > 其他好文 > 详细

架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

时间:2017-01-04 10:33:13      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:imp   dex   cat   读写   alt   oid   get   分享   stat   

ReentrantLock

有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级。

this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决方案,后面jdk干脆就提供了一个Lock类。

 

伪代码:

Lock lock = new ReentrantLock();//新建一个lock

Condition condition = lock.newCondition();//获取条件

method1(){

  try{

    lock.lock();

    代码块;

    lock.unlock();

    后续代码块;

  }

}

method2(){

  try{

    lock.lock();

    代码块;

    lock.signal();

  }

}

 

单condition操作:

 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 UseCondition {
 6 
 7     private Lock lock = new ReentrantLock();
 8     private Condition condition = lock.newCondition();
 9     
10     public void method1(){
11         try {
12             lock.lock();
13             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..");
14             Thread.sleep(3000);
15             System.out.println("当前线程:" + Thread.currentThread().getName() + "释放锁..");
16             condition.await();    // Object wait
17             System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行...");
18         } catch (Exception e) {
19             e.printStackTrace();
20         } finally {
21             lock.unlock();
22         }
23     }
24     
25     public void method2(){
26         try {
27             lock.lock();
28             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..");
29             Thread.sleep(3000);
30             System.out.println("当前线程:" + Thread.currentThread().getName() + "发出唤醒..");
31             condition.signal();        //Object notify
32         } catch (Exception e) {
33             e.printStackTrace();
34         } finally {
35             lock.unlock();
36         }
37     }
38     
39     public static void main(String[] args) {
40         
41         final UseCondition uc = new UseCondition();
42         Thread t1 = new Thread(new Runnable() {
43             @Override
44             public void run() {
45                 uc.method1();
46             }
47         }, "t1");
48         Thread t2 = new Thread(new Runnable() {
49             @Override
50             public void run() {
51                 uc.method2();
52             }
53         }, "t2");
54         t1.start();
55 
56         t2.start();
57     }
58     
59     
60     
61 }

执行结果:

技术分享

 
解释:线程1调用method1方法,线程2调用同一对象的method2方法,线程1先启动,线程1获取锁,进入method1的代码块,线程2也启动了,单是线程2被锁定,直到线程1发出lock.unlock()了,线程1才将锁释放,这时线程2获取锁,执行method2的代码块,线程2发出lock.signal(); 线程1才继续执行后续代码块。

 多condition操作:

  1 import java.util.concurrent.locks.Condition;
  2 import java.util.concurrent.locks.ReentrantLock;
  3 
  4 public class UseManyCondition {
  5 
  6     private ReentrantLock lock = new ReentrantLock();
  7     private Condition c1 = lock.newCondition();
  8     private Condition c2 = lock.newCondition();
  9     
 10     public void m1(){
 11         try {
 12             lock.lock();
 13             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m1等待..");
 14             c1.await();
 15             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m1继续..");
 16         } catch (Exception e) {
 17             e.printStackTrace();
 18         } finally {
 19             lock.unlock();
 20         }
 21     }
 22     
 23     public void m2(){
 24         try {
 25             lock.lock();
 26             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m2等待..");
 27             c1.await();
 28             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m2继续..");
 29         } catch (Exception e) {
 30             e.printStackTrace();
 31         } finally {
 32             lock.unlock();
 33         }
 34     }
 35     
 36     public void m3(){
 37         try {
 38             lock.lock();
 39             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m3等待..");
 40             c2.await();
 41             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m3继续..");
 42         } catch (Exception e) {
 43             e.printStackTrace();
 44         } finally {
 45             lock.unlock();
 46         }
 47     }
 48     
 49     public void m4(){
 50         try {
 51             lock.lock();
 52             System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
 53             c1.signalAll();
 54         } catch (Exception e) {
 55             e.printStackTrace();
 56         } finally {
 57             lock.unlock();
 58         }
 59     }
 60     
 61     public void m5(){
 62         try {
 63             lock.lock();
 64             System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
 65             c2.signal();
 66         } catch (Exception e) {
 67             e.printStackTrace();
 68         } finally {
 69             lock.unlock();
 70         }
 71     }
 72     
 73     public static void main(String[] args) {
 74         
 75         
 76         final UseManyCondition umc = new UseManyCondition();
 77         Thread t1 = new Thread(new Runnable() {
 78             @Override
 79             public void run() {
 80                 umc.m1();
 81             }
 82         },"t1");
 83         Thread t2 = new Thread(new Runnable() {
 84             @Override
 85             public void run() {
 86                 umc.m2();
 87             }
 88         },"t2");
 89         Thread t3 = new Thread(new Runnable() {
 90             @Override
 91             public void run() {
 92                 umc.m3();
 93             }
 94         },"t3");
 95         Thread t4 = new Thread(new Runnable() {
 96             @Override
 97             public void run() {
 98                 umc.m4();
 99             }
100         },"t4");
101         Thread t5 = new Thread(new Runnable() {
102             @Override
103             public void run() {
104                 umc.m5();
105             }
106         },"t5");
107         
108         t1.start();    // c1
109         t2.start();    // c1
110         t3.start();    // c2
111         
112 
113         try {
114             Thread.sleep(2000);
115         } catch (InterruptedException e) {
116             e.printStackTrace();
117         }
118 
119         t4.start();    // c1
120         try {
121             Thread.sleep(2000);
122         } catch (InterruptedException e) {
123             e.printStackTrace();
124         }
125         t5.start();    // c2
126         
127     }
128     
129     
130     
131 }

执行结果:

技术分享

解释:t1、t2线程都是用第一个condition c1,t3线程用第二个condition c2,t4线程发出c1.signalAll() 唤醒t1和t2线程,t5发出c2.signal()唤醒t3线程。

技术分享

架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

标签:imp   dex   cat   读写   alt   oid   get   分享   stat   

原文地址:http://www.cnblogs.com/sigm/p/6247346.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!