Java并发--读写锁(ReadWriteLock)

左手的ㄟ右手 2021-08-13 15:49 489阅读 0赞

ReadWriteLock

读写锁在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。

除了保证写操作对读操作的可见性以及并发性的提升之外,读写锁能够简化读写交互场景的编程方式。假设在程序中定义一个共享的用作缓存数据结构,它大部分时间提供读服务(例如查询和搜索),而写操作占有的时间很少,但是写操作完成之后的更新需要对后续的读服务可见。

一般情况下,读写锁的性能都会比排它锁好,因为大多数场景读是多于写的。在读多于写的情况下,读写锁能够提供比排它锁更好的并发性和吞吐量。Java并发包提供读写锁的实现是ReentrantReadWriteLock,它提供的特性如下表所示。

在这里插入图片描述

读写锁的接口与示例

ReadWriteLock仅定义了获取读锁和写锁的两个方法,即readLock()方法和writeLock()方法,而其实现——ReentrantReadWriteLock,除了接口方法之外,还提供了一些便于外界监控其内部工作状态的方法,这些方法以及描述如下表所示。

在这里插入图片描述

示例:

  1. package pers.zhang.part5;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.concurrent.locks.Lock;
  5. import java.util.concurrent.locks.ReentrantReadWriteLock;
  6. /** * @author zhang * @date 2020/1/20 - 19:02 */
  7. public class Cache {
  8. static Map<String, Object> map = new HashMap<String, Object>();
  9. static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  10. static Lock r = rwl.readLock();
  11. static Lock w = rwl.writeLock();
  12. //获取一个key对应的value
  13. public static final Object get(String key){
  14. r.lock();
  15. try{
  16. return map.get(key);
  17. }finally {
  18. r.unlock();
  19. }
  20. }
  21. //设置key对应的value,并返回旧的value
  22. public static final Object put(String key, Object value){
  23. w.lock();
  24. try{
  25. return map.put(key, value);
  26. }finally {
  27. w.unlock();
  28. }
  29. }
  30. //清空所有的内容
  31. public static final void clear(){
  32. w.lock();
  33. try{
  34. map.clear();
  35. }finally {
  36. w.unlock();
  37. }
  38. }
  39. }

上述示例中,Cache组合一个非线程安全的HashMap作为缓存的实现,同时使用读写锁的读锁和写锁来保证Cache是线程安全的。在读操作get(String key)方法中,需要获取读锁,这使得并发访问该方法时不会被阻塞。写操作put(String key,Object value)方法和clear()方法,在更新HashMap时必须提前获取写锁,当获取写锁后,其他线程对于读锁和写锁的获取均被阻塞,而只有写锁被释放之后,其他读写操作才能继续。Cache使用读写锁提升读操作的并发性,也保证每次写操作对所有的读写操作的可见性,同时简化了编程方式。

发表评论

表情:
评论列表 (有 0 条评论,489人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ReadWriteLock

    现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如

    相关 ReadWriteLock

           隐式锁Synchronized、重入锁ReetrantLock都是互斥锁、独占锁,即同一个锁只能每时每刻至多由一个线程来获持有。互斥,是一种保守策略,虽然避免了“

    相关 ReadWriteLock

    首先对于一个技术,存在就是为了解决某些技术难点。 为什么已经有ReentLock锁,却还要引入读写锁呢? 答案就是为了解决在 读多写少的场景下的性能问题,运用读写锁,能提高