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
证明读写操作是互斥的,只要出现写操作的过程就是互斥的