读写锁(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
原文地址:https://www.cnblogs.com/shen-smile/p/5142292.html