ReadWriteLock如何使用?
ReadWriteLock,读写锁。
ReentrantReadWriteLock 是 ReadWriteLock 的一种实现。
特点:
- 包含一个 ReadLock 和 一个 WriteLock 对象
- 读锁与读锁不互斥;读锁与写锁,写锁与写锁互斥
- 适合对共享资源有读和写操作,写操作很少,读操作频繁的场景
- 可以从写锁降级到读锁。获取写锁->获取读锁->释放写锁
- 无法从读锁升级到写锁
- 读写锁支持中断
- 写锁支持Condition;读锁不支持Condition
示例1--根据 key 获取 value 值
private ReadWriteLock lock = new ReentrantReadWriteLock();//定义读写锁 //根据 key 获取 value 值 public Object getValue(String key){ //使用读写锁的基本结构 lock.readLock().lock();//加读锁 Object value = null; try{ value = cache.get(key); if(value == null){ lock.readLock().unlock();//value值为空,释放读锁 lock.writeLock().lock();//加写锁,写入value值 try{ //重新检查 value值是否已经被其他线程写入 if(value == null){ value = "value";//写入数据 } }finally{ lock.writeLock().unlock(); } lock.readLock().lock(); } }finally{ lock.readLock().unlock(); } return value; }
示例2--多线程环境下的读写锁使用
package constxiong.interview; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 测试可重入 读写锁 * @author ConstXiong * @date 2019-06-10 11:19:42 */ public class TestReentrantReadWriteLock { private Map<String, Object> map = new HashMap<String, Object>(); private ReadWriteLock lock = new ReentrantReadWriteLock(); /** * 根据 key 获取 value * @param key * @return */ public Object get(String key) { Object value = null; lock.readLock().lock(); try { Thread.sleep(50L); value = map.get(key); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.readLock().unlock(); } return value; } /** * 设置key-value * @param key * @return */ public void set(String key, Object value) { lock.writeLock().lock(); try { Thread.sleep(50L); map.put(key, value); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.writeLock().unlock(); } } //测试5个线程读数据,5个线程写数据 public static void main(String[] args) { final TestReentrantReadWriteLock test = new TestReentrantReadWriteLock(); final String key = "lock"; final Random r = new Random(); for (int i = 0; i <5; i++) { new Thread(){ @Override public void run() { for (int j = 0; j <10; j++) { System.out.println(Thread.currentThread().getName() + " read value=" + test.get(key)); } } }.start(); new Thread(){ @Override public void run() { for (int j = 0; j <10; j++) { int value = r.nextInt(1000); test.set(key, value); System.out.println(Thread.currentThread().getName() + " write value=" + value); } } }.start(); } } }
- Java 自学指南
- Java 面试题汇总PC端浏览【点这里】
- Java知识图谱
- Java 面试题汇总小程序浏览,扫二维码
所有资源资源汇总于公众号