讀寫鎖(ReadWriteLock)的使用


Definition

讀寫鎖包含一對相關的鎖,讀鎖用於只讀操作,寫鎖用於寫操作。讀鎖可能由多個讀線程同時運行,寫鎖是唯一的。

 

Direction

1、讀鎖和寫鎖之間是互斥的,同一時間只能有一個在運行。但是可以有多個線程同時讀取數據。

2、寫入數據之前必須重新確認(ReCheck)狀態,因為其他的線程可能會拿到寫鎖再一次修改我們已經修改過的值。這是因為前一個線程拿到寫鎖之后,后面的線程會被阻塞。當前一個線程釋放寫鎖之后,被阻塞的線程會繼續運行完成被阻塞的部分代碼,所以才會出現這樣的情況。

3、當某一個線程上了寫鎖之后,自己仍然可以上讀鎖,之后在釋放寫鎖,這是一種降級(Downgrade)的處理方法。

 

Method

讀寫鎖(ReadWriteLock)包含如下兩個方法:

1.讀鎖

Lock readLock()

 

2.寫鎖

Lock writeLock()

 

Example

以下代碼在開始讀數據的時候上讀鎖,當有一個線程發現沒有數據時,釋放讀鎖,上寫鎖,開始寫入數據。

數據寫入完成后釋放寫鎖,並還原成讀鎖,實現了簡單的讀和寫之間的互斥。

示例代碼:

    private ReadWriteLock rwl = new ReentrantReadWriteLock();//定義讀寫鎖
    public Object getData(String key){
        //使用讀寫鎖的基本結構
        rwl.readLock().lock();
        Object value = null;
        try{
            value = cache.get(key);
            if(value == null){
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                try{
                    // Recheck state because another thread might have
                    // acquired write lock and changed state before we did.
                    if(value == null){
                        value = "aaaa";//寫入數據
                    }
                }finally{
                    rwl.writeLock().unlock();
                }
                rwl.readLock().lock();
            }
        }finally{
            rwl.readLock().unlock();
        }
        return value;
    }

 

讀寫鎖的完整使用示例:

 1 public class Test {
 2     public static void main(String[] args) {
 3         final Queue q = new Queue();
 4         for(int i=0;i<3;i++)
 5         {
 6             new Thread(){
 7                 public void run(){
 8                     while(true){
 9                         q.get();                        
10                     }
11                 }
12             }.start();
13 
14             new Thread(){
15                 public void run(){
16                     while(true){
17                         q.put(new Random().nextInt(10000));
18                     }
19                 }        
20             }.start();
21         }
22     }
23 }
24 
25 class Queue{
26     private Object data = null;//共享數據,只能有一個線程能寫該數據,但可以有多個線程同時讀該數據。
27     ReadWriteLock rwl = new ReentrantReadWriteLock();
28     public void get(){
29         rwl.readLock().lock();
30         try {
31             System.out.println(Thread.currentThread().getName() + " be ready to read data!");
32             Thread.sleep((long)(Math.random()*1000));
33             System.out.println(Thread.currentThread().getName() + "have read data :" + data);            
34         } catch (InterruptedException e) {
35             e.printStackTrace();
36         }finally{
37             rwl.readLock().unlock();
38         }
39     }
40     
41     public void put(Object data){
42         rwl.writeLock().lock();
43         try {
44             System.out.println(Thread.currentThread().getName() + " be ready to write data!");                    
45             Thread.sleep((long)(Math.random()*1000));
46             this.data = data;        
47             System.out.println(Thread.currentThread().getName() + " have write data: " + data);                    
48         } catch (InterruptedException e) {
49             e.printStackTrace();
50         }finally{
51             rwl.writeLock().unlock();
52         }
53     }
54 }

部分輸出結果如下:

Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-4have read data :null
Thread-0have read data :null
Thread-2have read data :null
Thread-3 be ready to write data!
Thread-3 have write data: 9763
Thread-3 be ready to write data!
Thread-3 have write data: 5187
Thread-3 be ready to write data!
Thread-3 have write data: 2135
Thread-1 be ready to write data!
Thread-1 have write data: 180
Thread-1 be ready to write data!
Thread-1 have write data: 5979
Thread-1 be ready to write data!
Thread-1 have write data: 9495
Thread-1 be ready to write data!
Thread-1 have write data: 6363
Thread-1 be ready to write data!
Thread-1 have write data: 31
Thread-1 be ready to write data!
Thread-1 have write data: 7530
Thread-1 be ready to write data!
Thread-1 have write data: 1354
Thread-5 be ready to write data!
Thread-5 have write data: 3580
Thread-5 be ready to write data!
Thread-5 have write data: 5534
Thread-5 be ready to write data!
Thread-5 have write data: 2522
Thread-5 be ready to write data!
Thread-5 have write data: 2926
Thread-4 be ready to read data!
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-2have read data :2926
Thread-0have read data :2926
Thread-4have read data :2926

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM