并发编程-concurrent指南-ReadWriteLock-ReentrantReadWriteLock(可重入读写锁)
几个线程都申请读锁,都能获取:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 几个线程都申请读锁,都能用
*/
public class MainRead {
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); public static void main(String[] args) {
final MainRead main = new MainRead(); new Thread(new Runnable() {
@Override
public void run() {
main.insert(Thread.currentThread());
}
}).start(); new Thread(new Runnable() {
@Override
public void run() {
main.insert(Thread.currentThread());
}
}).start();
} /**
* 几个线程都申请读锁,都能用
* @param thread
*/
public void insert(Thread thread){
reentrantReadWriteLock.readLock().lock();
try{
for(int i=0;i<5;i++){
System.out.println(thread.getName()+":"+i+",进行读操作");
TimeUnit.SECONDS.sleep(1);
}
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(thread.getName()+"释放读锁");
reentrantReadWriteLock.readLock().unlock();
}
}
}
结果:
Thread-0:0,进行读操作
Thread-1:0,进行读操作
Thread-1:1,进行读操作
Thread-0:1,进行读操作
Thread-0:2,进行读操作
Thread-1:2,进行读操作
Thread-0:3,进行读操作
Thread-1:3,进行读操作
Thread-0:4,进行读操作
Thread-1:4,进行读操作
Thread-0释放读锁
Thread-1释放读锁
几个线程,一个线程抢占了读锁,别的线程想用写锁时,需要等待读锁完成才行
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 几个线程,一个线程抢占了读锁,别的线程想用写锁时,需要等待读锁完成才行
*/
public class MainWrite {
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); public static void main(String[] args) {
final MainWrite main = new MainWrite(); new Thread(new Runnable() {
@Override
public void run() {
main.read(Thread.currentThread());
}
}).start(); new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
main.write(Thread.currentThread());
}
}).start();
} public void read(Thread thread){
reentrantReadWriteLock.readLock().lock();
try{
display(thread);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(thread.getName()+"释放读锁");
reentrantReadWriteLock.readLock().unlock();
}
} public void write(Thread thread){
reentrantReadWriteLock.writeLock().lock();
try{
display(thread);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(thread.getName()+"释放写锁");
reentrantReadWriteLock.writeLock().unlock();
}
} public void display(Thread thread) throws InterruptedException {
for(int i=0;i<5;i++){
System.out.println(thread.getName()+":"+i+",进行操作");
TimeUnit.SECONDS.sleep(1);
}
}
}
结果:
Thread-0:0,进行操作
Thread-0:1,进行操作
Thread-0:2,进行操作
Thread-0:3,进行操作
Thread-0:4,进行操作
Thread-0释放读锁
Thread-1:0,进行操作
Thread-1:1,进行操作
Thread-1:2,进行操作
Thread-1:3,进行操作
Thread-1:4,进行操作
Thread-1释放写锁
源码地址:https://github.com/qjm201000/concurrent_reentrantReadWriteLock.git
这样就大大提升了读操作的效率。
不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
并发编程-concurrent指南-ReadWriteLock-ReentrantReadWriteLock(可重入读写锁)的更多相关文章
- 018-并发编程-java.util.concurrent.locks之-ReentrantReadWriteLock可重入读写锁
一.概述 ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程.写线程和写线程同时访问.相对 ...
- 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁
上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和基本的方法,显示了怎样 ...
- 聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁
这篇讲讲ReentrantReadWriteLock可重入读写锁,它不仅是读写锁的实现,而且支持可重入性. 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁) 这篇讲了怎样模拟一个读写锁. 可重 ...
- 并发编程-concurrent指南-ReadWriteLock
ReadWriteLock也是一个接口,在它里面只定义了两个方法: public interface ReadWriteLock { /** * Returns the lock used for r ...
- Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock)
Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在学习Java的之前,你可能已经听说过读 ...
- java 可重入读写锁 ReentrantReadWriteLock 详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt206 读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只 ...
- 并发编程-concurrent指南-Lock-可重入锁(ReentrantLock)
可重入和不可重入的概念是这样的:当一个线程获得了当前实例的锁,并进入方法A,这个线程在没有释放这把锁的时候,能否再次进入方法A呢? 可重入锁:可以再次进入方法A,就是说在释放锁前此线程可以再次进入方法 ...
- 并发编程-concurrent指南-原子操作类-AtomicInteger
在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger
- 并发编程-concurrent指南-阻塞双端队列-链阻塞双端队列LinkedBlockingDeque
LinkedBlockingDeque是双向链表实现的阻塞队列.该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除): 在不能够插入元素时,它将阻塞住试图插入元 ...
随机推荐
- Matlab随笔之插值与拟合(下)
原文:Matlab随笔之插值与拟合(下) 1.二维插值之插值节点为网格节点 已知m x n个节点:(xi,yj,zij)(i=1…m,j=1…n),且xi,yi递增.求(x,y)处的插值z. Matl ...
- .net core service && angular项目 iis发布
项目结构 .net core 后端服务站点 angular 前端页面站点 项目模板来自于abp或者52abp .net core 后端服务站点发布到IIS 发布报错 .Net Core使用IIS部署出 ...
- 关于IOS7以及向下兼容音量控制问题
最近做个简单的播放界面,只是简单的设计到播放音频,ios系统自带播放有四个类可以播放音频 AVPlayer,AVAudioPlayer,MPMusicPlayerController,MPMovieP ...
- 毕业设计之感悟 —— UML 与 ER 图
今天毕业设计答辩,虽然我第一个上场,但是不是特别紧张,因为整个系统都是我写的.我以为自己天衣无缝,能应付所有老师的所有问题.事实上,我被老师教育了一番. 老师说我,毕业论文中没有一个类.我一开始比较懵 ...
- Linux学习之“fork函数”
n返回值: fork函数调用一次,但是返回两次:在子进程中返回0,在父进程中返回子进程ID,出错返回-1.通过返回值,可以确定是在父进程还是子进程中. n子进程和父进程继续执行fork调用之后的指令. ...
- p批处理替换目录下文本中的字符串
@echo off rem 进入批处理文件所在的路径 cd C:\Users\zxh\Desktop\ " as "abc" ***** rem 定义要替换的新旧字符串 ...
- Unicode 7.0.1中文支持非常好
简单测试了一下,7.0.1中文支持非常好.Delphi7下将UniConnection的useUnicode设置为False,Tokyo下设置为True,Charset空着即可. 问题要点:1.建数据 ...
- Android View 滚动边界的测量
最近一直在用Android TV的RecyclerView,实现视频搜索列表卡片的滚动显示,由于采用了双排滚动,打破了系统默认的单排滚动,且每一屏幕显示10个完整卡片5个半漏边卡片,每个完整卡片的左下 ...
- tftp的安装及配置
1.安装tftp服务客户端sudo apt-get install tftp 2.安装tftp服务器端sudo apt-get install tftpd 3.安装xinetd注意同类似的还有open ...
- Java实现Qt的SIGNAL-SLOT机制(保存到Map中,从而将它们关联起来,收到信号进行解析,最后反射调用)
SIGNAL-SLOT是Qt的一大特色,使用起来十分方便.在传统的AWT和Swing编程中,我们都是为要在 监听的对象上添加Listener监听器.被监听对象中保存有Listener的列表,当相关事件 ...