读写锁:多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。即:读的时候不允许写,写的时候不允许读,可以同时读。
synchronized关键字和普通的Lock构造的锁,会造成读与读之间的互斥,因此读写锁可提高性能。
例子1:三个线程同时对一个共享数据进行读写。
 1 import java.util.Random;2 import java.util.concurrent.locks.ReadWriteLock;3 import java.util.concurrent.locks.ReentrantReadWriteLock;4  5 public class ReadWriteLockTest {6         public static void main(String[] args) {7                final Queue queue = new Queue();8                for (int i = 0; i < 3; i++) {9                       new Thread() {
10                             public void run() {
11                                    while (true) {
12                                          queue.get();
13                                   }
14                            }
15
16                      }.start();
17
18                       new Thread() {
19                             public void run() {
20                                    while (true) {
21                                          queue.put( new Random().nextInt(10000));
22                                   }
23                            }
24
25                      }.start();
26               }
27
28        }
29 }
30
31 class Queue {
32         private Object data = null; // 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
33        ReadWriteLock rwl = new ReentrantReadWriteLock();
34
35         public void get() {
36                rwl.readLock().lock();
37                try {
38                      System. out.println(Thread.currentThread().getName() + " be ready to read data!");
39                      Thread. sleep((long) (Math. random() * 1000));
40                      System. out.println(Thread.currentThread().getName() + " have read data :" + data);
41               } catch (InterruptedException e) {
42                      e.printStackTrace();
43               } finally {
44                       rwl.readLock().unlock();
45               }
46        }
47
48         public void put(Object data) {
49
50                rwl.writeLock().lock();
51                try {
52                      System. out.println(Thread.currentThread().getName() + " be ready to write data!");
53                      Thread. sleep((long) (Math. random() * 1000));
54                       this.data = data;
55                      System. out.println(Thread.currentThread().getName() + " have write data: " + data);
56               } catch (InterruptedException e) {
57                      e.printStackTrace();
58               } finally {
59                       rwl.writeLock().unlock();
60               }
61
62        }
63 }

例子2:缓存实例
 1 import java.util.HashMap;2 import java.util.Map;3 import java.util.concurrent.locks.ReadWriteLock;4 import java.util.concurrent.locks.ReentrantReadWriteLock;5  6 public class CacheDemo {7  8         private static Map<String, Object> cache = new HashMap<String, Object>();9
10         private ReadWriteLock rwl = new ReentrantReadWriteLock();
11
12         public Object getData(String key) {
13                // 当线程开始读时,首先开始加上读锁
14                rwl.readLock().lock();
15               Object value = null;
16                try {
17                      value = cache.get(key);
18                       // 判断是否存在值
19                       if (value == null) {
20                             // 在开始写之前,首先要释放读锁,否则写锁无法拿到
21                             rwl.readLock().unlock();
22                             // 获取写锁开始写数据
23                             rwl.writeLock().lock();
24                             try {
25                                    // 再次判断该值是否为空,因为如果两个写线程都阻塞在这里,
26                                    // 当一个线程被唤醒后value的值为null则进行数据加载,当另外一个线程也被唤醒如果不判断就会执行两次写
27                                    if (value == null) {
28                                          value = "" ; // query 数据库
29                                           cache.put(key, value);
30                                   }
31                            } finally {
32                                    rwl.writeLock().unlock(); // 释放写锁
33                            }
34                             rwl.readLock().lock(); // 写完之后降级为读锁
35                      }
36               } finally {
37                       rwl.readLock().unlock(); // 释放读锁
38               }
39
40                return value;
41        }
42
43 }

转载于:https://www.cnblogs.com/zhangyuhang3/p/6872664.html

读写锁ReadWriteLock和缓存实例相关推荐

  1. JUC系列(八)| 读写锁-ReadWriteLock

    多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...

  2. 信号量semaphore 读写锁ReadWriteLock 倒计时器CountDownLatch 循环栅栏 CyclicBarrier 线程阻塞工具类LockSupport...

    信号量semaphore    允许多个线程同时访问 读写锁ReadWriteLock   在频繁的读写耗时中,读之间不阻塞 倒计时器CountDownLatch    obj = new Count ...

  3. Java多线程学习十六:读写锁 ReadWriteLock 获取锁有哪些规则

    读写锁 ReadWriteLock 获取锁有哪些规则呢? 在没有读写锁之前,我们假设使用普通的 ReentrantLock,那么虽然我们保证了线程安全,但是也浪费了一定的资源,因为如果多个读操作同时进 ...

  4. 分布式读写锁 ReadWriteLock

    基于Redis的Redisson分布式可重入读写锁RReadWriteLock ,实现了 juc lock包下的 ReadWriteLock接口. 分布式可重入读写锁允许同时有多个读锁和一个写锁处于加 ...

  5. 读写锁ReadWriteLock

    为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率. Java中读写锁有个接口java.util ...

  6. Java之读写锁ReadWriteLock实现

    一.为什么需要读写锁? 与传统锁不同的是读写锁的规则是可以共享读,但只能一个写,总结起来为:读读不互斥,读写互斥,写写互斥,而一般的独占锁是:读读互斥,读写互斥,写写互斥,而场景中往往读远远大于写,读 ...

  7. 对变量移位顺序读写_Java多线程并发读写锁ReadWriteLock实现原理剖析

    关于读写锁 Java语法层面的synchronized锁和JDK内置可重入锁ReentrantLock我们都经常会使用,这两种锁都属于纯粹的独占锁,也就是说这些锁任意时刻只能由一个线程持有,其它线程都 ...

  8. 读写锁(ReadwriteLock)

    读写锁 多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源应该可以同时但是,如果有一个线程想去写共享资源,就不应该再有其它线程可以对该资源进行读或写 结果 总结 读-读能共存 读- ...

  9. Java并发原理抽丝剥茧,读写锁ReadWriteLock实现深入剖析

    跟着作者的65节课彻底搞懂Java并发原理专栏,一步步彻底搞懂Java并发原理. 作者简介:笔名seaboat,擅长工程算法.人工智能算法.自然语言处理.架构.分布式.高并发.大数据和搜索引擎等方面的 ...

最新文章

  1. 手机数据抓包入门教程
  2. 网站SEO优化中导航对用户体验的重要性
  3. Centos7安装配置Xhgui
  4. java+jtextfield+取值_[求助]JTextfield 取值问题!
  5. [css] 举例说明伪类:focus-within的用法
  6. JAGUARSDN1网络的开机自动启动 禁用,WIFI模块的启动关闭控制
  7. python 去除nan inf_Python实现半自动评分卡建模(附代码)
  8. tensorflow 保存训练loss_tensorflow2.0保存和加载模型 (tensorflow2.0官方教程翻译)
  9. php伪静态之APACHE配置篇
  10. 「快学springboot」SpringBoot整合freeMark模板引擎
  11. 覆盖与隐藏的区别 (一个列子)
  12. nginx源码包编译安装
  13. 1110 Complete Binary Tree (25 分)(搜索)
  14. 域名被封(微信)后的思索
  15. 为企业选择最合适的SSL证书
  16. 【概率论】边缘分布和联合分布
  17. 6款令人相见恨晚的在线搜索网站,成年后都会要用上,了解一下!
  18. 华为手机最大屏是几英寸的_华为有史以来最大屏幕的手机,屏幕尺寸高达7.12寸,性价比很好!...
  19. referenced libraries
  20. MacBook 安装 win10 系统的方法

热门文章

  1. html取 输入框中的值,jquery获取input输入框中的值
  2. (1)搞一搞 seata 之 基础环境搭建
  3. 南达科他州立大学计算机科学,关于举行南达科他州立大学Srinivas Janaswamy博士学术报告的通知...
  4. 支持向量机python代码_用TensorFlow实现多类支持向量机的示例代码
  5. yandex注册验证码怎么填_注册资本到底怎么填?
  6. java axis2 jar_Java axis2.jar包详解及缺少jar包错误分析
  7. 交叉熵代价函数——当我们用sigmoid函数作为神经元的激活函数时,最好使用交叉熵代价函数来替代方差代价函数,以避免训练过程太慢...
  8. Spark技术在京东智能供应链预测的应用——按照业务进行划分,然后利用scikit learn进行单机训练并预测...
  9. DNS同时占用UDP和TCP端口53——传输数据超过512时候用tcp,DNS服务器可以配置仅支持UDP查询包...
  10. ES mapping可以修改include_in_all,也可以修改index_options,norm,但是无法修改_all属性!...