读写锁在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。
只需在读操作时获取读锁,写操作时获取写锁。当写锁被获取时,后续的读写操作都会被阻塞,写锁释放后,所有操作继续执行。
该锁支持重进入。
写锁能够降级成为读锁。
readLock()、writeLock()
简单示例:
1 class Cache{ 2 static Map<String, Object> map = new HashMap<String, Object>(); 3 static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); 4 static Lock r = rwLock.readLock(); 5 static Lock w = rwLock.writeLock(); 6 //获取一个key对应的value 7 public static final Object get(String key){ 8 r.lock(); 9 try { 10 return map.get(key); 11 }finally { 12 r.unlock(); 13 } 14 } 15 //设置key对应的value值 16 public static final Object put(String key, Object value){ 17 w.lock(); 18 try { 19 return map.put(key, value); 20 }finally { 21 w.unlock(); 22 } 23 } 24 //清空所有内容 25 public static final void clear(){ 26 w.lock(); 27 try { 28 map.clear(); 29 }finally { 30 w.unlock(); 31 } 32 } 33 }
锁降级的示例:
1 class LockDec{ 2 static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); 3 static Lock readLock = rwLock.readLock(); 4 static Lock writeLock = rwLock.writeLock(); 5 public volatile boolean update = false; 6 public void processData(){ 7 readLock.lock(); 8 if (!update){ 9 //必须先释放读锁 10 readLock.unlock(); 11 //锁降级从写锁获取到开始 12 writeLock.lock(); 13 try { 14 if (!update){ 15 //准备数据的流程 16 update = true; 17 } 18 readLock.lock(); 19 }finally { 20 writeLock.unlock(); 21 } 22 //锁降级完成,写锁降级为读锁 23 } 24 try { 25 //使用数据的流程 26 }finally { 27 readLock.unlock(); 28 } 29 } 30 }
当数据发生变更后 ,update变量被设置为true,此时所有访问processData()方法的线程都能感知到变化。