ReentrantReadWriteLock的相关使用

ReentrantLock具有完全互斥排他的效果,同一时间只有一个线程执行ReentrantLock.lock()方法后面的任务,这样虽然能够保证线程安全性,但是效率是比较低的

ReentrantReadWriteLock可以加快运行效率

ReentrantReadWriteLock读写锁有两个锁,读锁和写锁,读锁是共享锁,写锁是排他锁:

  • 读锁与读锁不互斥
  • 写锁与写锁互斥
  • 读锁与写锁互斥
  • 写锁与读锁互斥

ReentrantReadWriteLock

读锁与读锁不互斥

 1 public class Test01 {
 2     private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 3     public void read(){
 4         try {
 5             lock.readLock().lock();
 6             System.out.println("获取读锁"+Thread.currentThread().getName()+" "+System.currentTimeMillis());
 7             Thread.sleep(10000);
 8         } catch (InterruptedException e) {
 9             e.printStackTrace();
10         } finally {
11             lock.readLock().unlock();
12         }
13     }
14 
15     public static void main(String[] args) {
16         Test01 test = new Test01();
17         Runnable runnable = new Runnable() {
18             @Override
19             public void run() {
20                 test.read();
21             }
22         };
23         Thread a = new Thread(runnable);
24         a.setName("A");
25         Thread b = new Thread(runnable);
26         b.setName("B");
27         a.start();
28         b.start();
29     }
30 }

-------------------------------------------------console-------------------------------------------------

获取读锁A 1539155032025
获取读锁B 1539155032025

打印结果显示线程A,B同时读取锁,证明多个线程获得读锁是不互斥的,使用读锁可以提高程序运行效率

写锁与写锁互斥

 1 public class Test02 {
 2     private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 3     public void write(){
 4         try {
 5             lock.writeLock().lock();
 6             System.out.println("获取写锁"+Thread.currentThread().getName()+" "+System.currentTimeMillis());
 7             Thread.sleep(10000);
 8         } catch (InterruptedException e) {
 9             e.printStackTrace();
10         } finally {
11             lock.writeLock().unlock();
12         }
13     }
14 
15     public static void main(String[] args) {
16         Test02 test = new Test02();
17         Runnable runnable = new Runnable() {
18             @Override
19             public void run() {
20                 test.write();
21             }
22         };
23         Thread a = new Thread(runnable);
24         a.setName("A");
25         Thread b = new Thread(runnable);
26         b.setName("B");
27         a.start();
28         b.start();
29     }
30 }

-------------------------------------------------console-------------------------------------------------

获取写锁A 1539155285755
获取写锁B 1539155295757

证明同一时间只允许一个线程执行lock()方法后面的代码

读锁与写锁互斥,写锁与读锁互斥

 1 public class Test03 {
 2     private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 3     public void read(){
 4         try {
 5 
 6             lock.readLock().lock();
 7             System.out.println("获取读锁"+Thread.currentThread().getName()+" "+System.currentTimeMillis());
 8             Thread.sleep(10000);
 9         } catch (InterruptedException e) {
10             e.printStackTrace();
11         } finally {
12             lock.readLock().unlock();
13         }
14     }
15 
16     public void write(){
17         try {
18             lock.writeLock().lock();
19             System.out.println("获取写锁"+Thread.currentThread().getName()+" "+System.currentTimeMillis());
20             Thread.sleep(10000);
21         } catch (InterruptedException e) {
22             e.printStackTrace();
23         } finally {
24             lock.writeLock().unlock();
25         }
26     }
27 
28     public static void main(String[] args) {
29         Test03 test = new Test03();
30 
31         Thread a = new Thread(new Runnable() {
32             @Override
33             public void run() {
34                 test.read();
35             }
36         });
37         a.setName("A");
38         Thread b = new Thread(new Runnable() {
39             @Override
40             public void run() {
41                 test.write();
42             }
43         });
44         b.setName("B");
45         a.start();
46         b.start();
47     }
48 }

-------------------------------------------------console-------------------------------------------------

获取读锁A 1539155559525
获取写锁B 1539155569525

证明读写操作是互斥的,只要出现写操作的过程就是互斥的

原文地址:https://www.cnblogs.com/qf123/p/9766551.html