1. 程式人生 > >鎖 Lock、重入鎖、寫入鎖

鎖 Lock、重入鎖、寫入鎖

lee 但是 sleep rac ued finally println ava one

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、重入鎖、寫入鎖