线程高级篇-读写锁ReentrantReadWriteLock
转载原文:http://blog.csdn.net/john8169/article/details/53228016
读写锁: 分为读锁和写锁,多个读锁不互斥,读锁和写锁互斥,这是有JVM自己控制的.如果代码只能读取数据,可以多人同时读,不能同时写,上读锁,
如果代码要修改数据,只能有一个人写,而且不能同时读取.上写锁.
线程进入写锁的前提条件:
没有其他线程的读锁和写锁;
线程进入读锁的前提条件:
没有其他线程的写锁或写请求
(a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。
(b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵.
(c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。
(d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。
(e).WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不能使用Condition,否则抛出UnsupportedOperationException异常。
package com.imooc.locks; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class Queue { private Object data = null;//共享数据,只能有一个线程写该数据,但可以多个线程读取该数据 //读写锁
ReadWriteLock rwl = new ReentrantReadWriteLock(); // 相当于读操作
public void get() {
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + "have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.readLock().unlock();
}
} // 相当于写操作
public void put(Object data) {
rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
Thread.sleep((long) (Math.random() * 1000));
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.writeLock().unlock();
}
} }
package com.imooc.locks;
import java.util.Random;
public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue q3 = new Queue();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
q3.get();
}
}
}.start();
new Thread() {
public void run() {
while (true) {
q3.put(new Random().nextInt(10000));
}
}
}.start();
}
}
}
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-0have read data :null
Thread-2have read data :null
Thread-4have read data :null
Thread-1 be ready to write data!
Thread-1 have write data: 3101
Thread-1 be ready to write data!
Thread-1 have write data: 8258
Thread-1 be ready to write data!
Thread-1 have write data: 7242
Thread-3 be ready to write data!
Thread-3 have write data: 4810
Thread-5 be ready to write data!
Thread-5 have write data: 7597
Thread-5 be ready to write data!
Thread-5 have write data: 8800
Thread-0 be ready to read data!
Thread-4 be ready to read data!
Thread-2 be ready to read data!
Thread-0have read data :8800
Thread-2have read data :8800
Thread-4have read data :8800
Thread-1 be ready to write data!
Thread-1 have write data: 6606
Thread-1 be ready to write data!
Thread-1 have write data: 5436
Thread-1 be ready to write data!
Thread-1 have write data: 3912
Thread-1 be ready to write data!
Thread-1 have write data: 7689
Thread-3 be ready to write data!
Thread-3 have write data: 3102
Thread-3 be ready to write data!
Thread-3 have write data: 466
Thread-3 be ready to write data!
Thread-3 have write data: 7377
Thread-3 be ready to write data!
Thread-3 have write data: 5461
Thread-3 be ready to write data!
Thread-3 have write data: 175
Thread-3 be ready to write data!
Thread-3 have write data: 8805
Thread-3 be ready to write data!
Thread-3 have write data: 8898
Thread-5 be ready to write data!
Thread-5 have write data: 8823
Thread-5 be ready to write data!
Thread-5 have write data: 5615
Thread-5 be ready to write data!
Thread-5 have write data: 8118
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-0have read data :8118
Thread-2have read data :8118
Thread-4have read data :8118
Thread-1 be ready to write data!
Thread-1 have write data: 5314
Thread-1 be ready to write data!
从打印结果可以看出:
多个线程可以同时读取数据,但是只有一个线程可以写数据;
线程高级篇-读写锁ReentrantReadWriteLock的更多相关文章
- UNIX环境高级编程——线程同步之读写锁以及属性
读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...
- Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...
- java 可重入读写锁 ReentrantReadWriteLock 详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt206 读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只 ...
- [图解Java]读写锁ReentrantReadWriteLock
图解ReentrantReadWriteLock 如果之前使用过读写锁, 那么可以直接看本篇文章. 如果之前未使用过, 那么请配合我的另一篇文章一起看:[源码分析]读写锁ReentrantReadWr ...
- 轻松掌握java读写锁(ReentrantReadWriteLock)的实现原理
转载:https://blog.csdn.net/yanyan19880509/article/details/52435135 前言 前面介绍了java中排它锁,共享锁的底层实现机制,本篇再进一步, ...
- [源码分析]读写锁ReentrantReadWriteLock
一.简介 读写锁. 读锁之间是共享的. 写锁是独占的. 首先声明一点: 我在分析源码的时候, 把jdk源码复制出来进行中文的注释, 有时还进行编译调试什么的, 为了避免和jdk原生的类混淆, 我在类前 ...
- Java并发(十):读写锁ReentrantReadWriteLock
先做总结: 1.为什么用读写锁 ReentrantReadWriteLock? 重入锁ReentrantLock是排他锁,在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服 ...
- 深入浅出 Java Concurrency (13): 锁机制 part 8 读写锁 (ReentrantReadWriteLock) (1)
从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock). ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念.前面的章节中一 ...
- Java读写锁(ReentrantReadWriteLock)学习
什么是读写锁 平时,我们常见的synchronized和Reentrantlock基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,哪怕是读操作.而读写锁是维护了一对锁(一个读锁和一个写锁), ...
随机推荐
- 弹性布局详解——5个div让你学会弹性布局
前 言 JRedu 在网页制作过程中,布局是我们最重要的一个环节.可以说布局的好坏直接影响到整个网页的成败!布局成,则事半功倍:布局败,则事倍功半. 随着移动互联的到来,响应式网站风靡.这也就兴 ...
- Modelsimse10.1如何编译altera库文件以支持IP仿真
前言 se版本默认没有ip之类的库支持,如果你用到了pll之类的ip,仿真前就得把库编译好. 流程 本例用的是altera的verilog库. 1.首先在modelsim安装目录下新建altera文件 ...
- css的一些问题
background-size ie8不支持怎么解决? background-size这个属性是css3,新增的属性,现在很多浏览器已经支持了,但是IE系列的浏览器却没有支持,比如IE8,下面介绍下如 ...
- hibernate中对象的3种状态----瞬时态、持久态、脱管态
Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...
- 浅谈分析表格布局与Div+CSS布局的区别
(1)表格布局 表格布局容易掌握,布局方便.但表格布局需要通过表格的间距或者使用透明的gif图片来填充布局板块间的间距,这样布局的网页中表格会生成大量难以阅读和维护的代码:而且表格布局的网页要等整个表 ...
- Qt将窗体变为顶层窗体
//重载resizeEvent和moveEvent两个函数,以保证窗体大小和位置改变后能时刻记住其位置 QRect curGemRect = mpWindow->geometry(); //激活 ...
- ActionBar+DrawerLayout实现网易新闻客户端首页
一.概述 随着android版本的不断的更新,google推出了越来越多的高级组件,采用这些官方组件我们可以方便的实现一些以前需要通过复杂编码或者使用第三方组件才能实现的效果,比如slidingmen ...
- Java 编写小程序,下载指定网页上的所有图片
使用Java编写一个小程序,可以根据指定的网页地址,下载网页中的所有图片:使用到网络编程.线程池.IO和UUID的技术.具体代码如下: import java.io.File; import java ...
- Android MediaCodec硬编兼容性测试方案
作者:阿宝 更新:2016-08-15 来源:彩色世界(https://blog.hz601.org/2016/08/15/android-mediacodec-hardcode-compatibil ...
- 谈谈Golang中goroutine的调度问题
goroutine的调度问题,同样也是我之前面试的问题,不过这个问题我当时并不是很清楚,回来以后立马查阅资料,现整理出来备忘. 有一些预备知识需要说明,就是操作系统中的线程.操作系统中的线程分为两种: ...