锁 Lock重入锁写入锁

Posted here

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了锁 Lock重入锁写入锁相关的知识,希望对你有一定的参考价值。

ReentrantLock 重入锁 类似于synchronize 区别与写法上,在需要进行同步的代码部分加上锁定,但不要忘记最后一定要释放锁定,
不然会造成锁永远无法释放,其他线程永远进不来的结果。
eg:
技术分享
 1 package com.zym.height.Lock01;
 2 
 3 import java.util.concurrent.locks.Lock;
 4 import java.util.concurrent.locks.ReentrantLock;
 5 
 6 public class UseReentrantLock {
 7     
 8     private Lock lock = new ReentrantLock();
 9     
10     public void method1(){
11         try {
12             lock.lock();
13             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method1..");
14             Thread.sleep(1000);
15             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method1..");
16             Thread.sleep(1000);
17         } catch (InterruptedException e) {
18             e.printStackTrace();
19         } finally {
20             
21             lock.unlock();
22         }
23     }
24     
25     public void method2(){
26         try {
27             lock.lock();
28             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method2..");
29             Thread.sleep(2000);
30             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method2..");
31             Thread.sleep(1000);
32         } catch (InterruptedException e) {
33             e.printStackTrace();
34         } finally {
35             
36             lock.unlock();
37         }
38     }
39     
40     public static void main(String[] args) {
41 
42         final UseReentrantLock ur = new UseReentrantLock();
43         Thread t1 = new Thread(new Runnable() {
44             @Override
45             public void run() {
46                 ur.method1();
47                 ur.method2();
48             }
49         }, "t1");
50 
51         t1.start();
52         try {
53             Thread.sleep(10);
54         } catch (InterruptedException e) {
55             e.printStackTrace();
56         }
57         //System.out.println(ur.lock.getQueueLength());
58     }
59     
60     
61 }
View Code


Lock Condition
公平锁和非公平锁
Lock lock = new ReentrantLock();    
lock用法:
tryLock():尝试获得锁(在给定的时间内尝试获得锁),获得结果用true/false返回。
isFair():是否是公平锁。
isLocked():是否锁定。
getHoldCount():查询当前线程保持此锁的个数,也就是调用lock()次数。
lockInterruptibly():优先响应中断的锁。
getQueueLength():返回正在等待获取此锁的线程数。
getWaitQueueLength():返回等待与锁定相关的给定条件Condition的线程数。
hasQueuedThread(Thread thread):查询指定的线程是否正在等待此锁。
hasQueuedThreads():查询是否有线程正在等待此锁。
hasWaiters():查询是否有线程正在等待与此锁定有关的condition条件。
技术分享
 1 package com.zym.height.Lock01;
 2 
 3 import java.util.concurrent.locks.Condition;
 4 import java.util.concurrent.locks.Lock;
 5 import java.util.concurrent.locks.ReentrantLock;
 6 
 7 public class UseCondition {
 8 
 9     private Lock lock = new ReentrantLock();
10     private Condition condition = lock.newCondition();
11     
12     public void method1(){
13         try {
14             lock.lock();
15             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入等待状态..");
16             Thread.sleep(3000);
17             System.out.println("当前线程:" + Thread.currentThread().getName() + "释放锁..");
18             condition.await();    // Object wait
19             System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行...");
20         } catch (Exception e) {
21             e.printStackTrace();
22         } finally {
23             lock.unlock();
24         }
25     }
26     
27     public void method2(){
28         try {
29             lock.lock();
30             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..");
31             Thread.sleep(3000);
32             System.out.println("当前线程:" + Thread.currentThread().getName() + "发出唤醒..");
33             condition.signal();        //Object notify
34         } catch (Exception e) {
35             e.printStackTrace();
36         } finally {
37             lock.unlock();
38         }
39     }
40     
41     public static void main(String[] args) {
42         
43         final UseCondition uc = new UseCondition();
44         Thread t1 = new Thread(new Runnable() {
45             @Override
46             public void run() {
47                 uc.method1();
48             }
49         }, "t1");
50         Thread t2 = new Thread(new Runnable() {
51             @Override
52             public void run() {
53                 uc.method2();
54             }
55         }, "t2");
56         t1.start();
57 
58         t2.start();
59     }
60     
61     
62     
63 }
UseCondition
技术分享
  1 package com.zym.height.Lock01;
  2 
  3 import java.util.concurrent.locks.Condition;
  4 import java.util.concurrent.locks.ReentrantLock;
  5 
  6 public class UseManyCondition {
  7 
  8     private ReentrantLock lock = new ReentrantLock();
  9     private Condition c1 = lock.newCondition();
 10     private Condition c2 = lock.newCondition();
 11     
 12     public void m1(){
 13         try {
 14             lock.lock();
 15             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m1等待..");
 16             c1.await();
 17             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m1继续..");
 18         } catch (Exception e) {
 19             e.printStackTrace();
 20         } finally {
 21             lock.unlock();
 22         }
 23     }
 24     
 25     public void m2(){
 26         try {
 27             lock.lock();
 28             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m2等待..");
 29             c1.await();
 30             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m2继续..");
 31         } catch (Exception e) {
 32             e.printStackTrace();
 33         } finally {
 34             lock.unlock();
 35         }
 36     }
 37     
 38     public void m3(){
 39         try {
 40             lock.lock();
 41             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m3等待..");
 42             c2.await();
 43             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m3继续..");
 44         } catch (Exception e) {
 45             e.printStackTrace();
 46         } finally {
 47             lock.unlock();
 48         }
 49     }
 50     
 51     public void m4(){
 52         try {
 53             lock.lock();
 54             System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
 55             c1.signalAll();
 56         } catch (Exception e) {
 57             e.printStackTrace();
 58         } finally {
 59             lock.unlock();
 60         }
 61     }
 62     
 63     public void m5(){
 64         try {
 65             lock.lock();
 66             System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
 67             c2.signal();
 68         } catch (Exception e) {
 69             e.printStackTrace();
 70         } finally {
 71             lock.unlock();
 72         }
 73     }
 74     
 75     public static void main(String[] args) {
 76         
 77         
 78         final UseManyCondition umc = new UseManyCondition();
 79         Thread t1 = new Thread(new Runnable() {
 80             @Override
 81             public void run() {
 82                 umc.m1();
 83             }
 84         },"t1");
 85         Thread t2 = new Thread(new Runnable() {
 86             @Override
 87             public void run() {
 88                 umc.m2();
 89             }
 90         },"t2");
 91         Thread t3 = new Thread(new Runnable() {
 92             @Override
 93             public void run() {
 94                 umc.m3();
 95             }
 96         },"t3");
 97         Thread t4 = new Thread(new Runnable() {
 98             @Override
 99             public void run() {
100                 umc.m4();
101             }
102         },"t4");
103         Thread t5 = new Thread(new Runnable() {
104             @Override
105             public void run() {
106                 umc.m5();
107             }
108         },"t5");
109         
110         t1.start();    // c1
111         t2.start();    // c1
112         t3.start();    // c2
113         
114 
115         try {
116             Thread.sleep(2000);
117         } catch (InterruptedException e) {
118             e.printStackTrace();
119         }
120 
121         t4.start();    // c1
122         try {
123             Thread.sleep(2000);
124         } catch (InterruptedException e) {
125             e.printStackTrace();
126         }
127         t5.start();    // c2
128         
129     }
130     
131     
132     
133 }
UseManyCondition
技术分享
 1 package com.zym.height.Lock01;
 2 
 3 import java.util.concurrent.locks.ReentrantLock;
 4 /**
 5  * lock.getHoldCount()方法:只能在当前调用线程内部使用,不能再其他线程中使用
 6  * 那么我可以在m1方法里去调用m2方法,同时m1方法和m2方法都持有lock锁定即可 测试结果holdCount数递增
 7  *
 8  */
 9 public class TestHoldCount {
10 
11     //重入锁
12     private ReentrantLock lock = new ReentrantLock();
13     
14     public void m1(){
15         try {
16             lock.lock();
17             System.out.println("进入m1方法,holdCount数为:" + lock.getHoldCount());
18             
19             //调用m2方法
20             m2();
21             
22         } catch (Exception e) {
23             e.printStackTrace();
24         } finally {
25             lock.unlock();
26         }
27     }
28     
29     public void m2(){
30         try {
31             lock.lock();
32             System.out.println("进入m2方法,holdCount数为:" + lock.getHoldCount());
33         } catch (Exception e) {
34             e.printStackTrace();
35         } finally {
36             lock.unlock();
37         }
38     }
39     
40     
41     public static void main(String[] args) {
42         TestHoldCount thc = new TestHoldCount();
43         thc.m1();
44     }
45 }
Test HoldCondition



ReentrantReadWriteLock

读写锁 其核心就是实现读写分离的锁,在高并发访问下,尤其是读多写少的情况下,性能要远高于重入锁,在同一时间,只能有一个线程
      可以进行访问被锁定的代码,那么读写锁则不同,其本质是分层两个锁,即读锁、写锁。在读锁下,多个线程可以并发的进行访问,
      但是在写锁的时候,只能一个一个的顺序访问。
口诀:读读共享,写写互斥,读写互斥。
技术分享
 1 package com.zym.height.Lock01;
 2 
 3 import java.util.concurrent.locks.ReentrantReadWriteLock;
 4 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
 5 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
 6 
 7 public class UseReentrantReadWriteLock {
 8 
 9     private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
10     private ReadLock readLock = rwLock.readLock();
11     private WriteLock writeLock = rwLock.writeLock();
12     
13     public void read(){
14         try {
15             readLock.lock();
16             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
17             Thread.sleep(3000);
18             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
19         } catch (Exception e) {
20             e.printStackTrace();
21         } finally {
22             readLock.unlock();
23         }
24     }
25     
26     public void write(){
27         try {
28             writeLock.lock();
29             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
30             Thread.sleep(3000);
31             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
32         } catch (Exception e) {
33             e.printStackTrace();
34         } finally {
35             writeLock.unlock();
36         }
37     }
38     
39     public static void main(String[] args) {
40         
41         final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();
42         
43         Thread t1 = new Thread(new Runnable() {
44             @Override
45             public void run() {
46                 urrw.read();
47             }
48         }, "t1");
49         Thread t2 = new Thread(new Runnable() {
50             @Override
51             public void run() {
52                 urrw.read();
53             }
54         }, "t2");
55         Thread t3 = new Thread(new Runnable() {
56             @Override
57             public void run() {
58                 urrw.write();
59             }
60         }, "t3");
61         Thread t4 = new Thread(new Runnable() {
62             @Override
63             public void run() {
64                 urrw.write();
65             }
66         }, "t4");        
67         
68 //        t1.start();
69 //        t2.start();
70         
71 //        t1.start(); // R 
72 //        t3.start(); // W
73         
74         t3.start();
75         t4.start();
76         
77         
78         
79         
80         
81         
82         
83         
84     }
85 }
View Code

 





















































以上是关于锁 Lock重入锁写入锁的主要内容,如果未能解决你的问题,请参考以下文章

重入锁

并发编程-concurrent指南-Lock-可重入锁(ReentrantLock)

并发编程的锁机制:synchronized和lock

微服务架构之:Redisson分布式可重入锁原理

Java并发编程之重入锁与读写锁

音视频开发之旅(54) - Lock重入锁读写锁和Condition