几个线程都申请读锁,都能获取

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(可重入读写锁)的更多相关文章

  1. 018-并发编程-java.util.concurrent.locks之-ReentrantReadWriteLock可重入读写锁

    一.概述 ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程.写线程和写线程同时访问.相对 ...

  2. 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁

    上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和基本的方法,显示了怎样 ...

  3. 聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁

    这篇讲讲ReentrantReadWriteLock可重入读写锁,它不仅是读写锁的实现,而且支持可重入性. 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁) 这篇讲了怎样模拟一个读写锁. 可重 ...

  4. 并发编程-concurrent指南-ReadWriteLock

    ReadWriteLock也是一个接口,在它里面只定义了两个方法: public interface ReadWriteLock { /** * Returns the lock used for r ...

  5. Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock)

    Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在学习Java的之前,你可能已经听说过读 ...

  6. java 可重入读写锁 ReentrantReadWriteLock 详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt206 读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只 ...

  7. 并发编程-concurrent指南-Lock-可重入锁(ReentrantLock)

    可重入和不可重入的概念是这样的:当一个线程获得了当前实例的锁,并进入方法A,这个线程在没有释放这把锁的时候,能否再次进入方法A呢? 可重入锁:可以再次进入方法A,就是说在释放锁前此线程可以再次进入方法 ...

  8. 并发编程-concurrent指南-原子操作类-AtomicInteger

    在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger

  9. 并发编程-concurrent指南-阻塞双端队列-链阻塞双端队列LinkedBlockingDeque

    LinkedBlockingDeque是双向链表实现的阻塞队列.该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除): 在不能够插入元素时,它将阻塞住试图插入元 ...

随机推荐

  1. 【从翻译mos文章】在oracle db 11gR2版本号被启用 Oracle NUMA 支持

    在oracle db 11gR2版本号被启用 Oracle NUMA 支持 参考原始: Enable Oracle NUMA support with Oracle Server Version 11 ...

  2. 将exe和dll文件打包成单一的启动文件

    当我们用 VS 或其它编程工具生成了可执行exe要运行它必须要保证其目录下有一大堆dll库文件,看起来很不爽,用专业的安装程序生成软件又显得繁琐,下面这个方法教你如何快速把exe文件和dll文件打包成 ...

  3. WPF后台生成datatemplate(TreeViewItem例子)

    public void loadCheckListDataTemplate(TreeViewItem tvi) { DataTemplate cdt = new DataTemplate(); Fra ...

  4. 数据绑定(四)使用DataContext作为Binding的Source

    原文:数据绑定(四)使用DataContext作为Binding的Source DataContext属性被定义在FrameworkElement类里,这个类是WPF控件的基类,这意味着所有WPF控件 ...

  5. 不能继承于QObject的类就一定不能使用信号槽?(用一个代理类进行发射就行了)

    首先不能继承QObject的情况在开发中遇到得并不多,笔者在一年多的Qt项目开发中只遇到两三次.而且都是因为引进了第三方库导致编译过程中报错. 要想解决这个问题其实不难,因为笔者遇到的问题都是想定义一 ...

  6. 不要困在自己建造的盒子里——写给.NET程序员(附精彩评论)

    此文章的主旨是希望过于专注.NET程序员在做好工作.写好.NET程序的同时,能分拨出一点时间接触一下.NET之外的东西(例如10%-20%的时间),而不是鼓动大家什么都去学最后什么都学不精,更不是说. ...

  7. Windows10 使用Virtual Box一启动虚拟机就蓝屏(错误代码SYSTEM_SERVICE_EXCEPTION)解决方案

    原文:Windows10 使用Virtual Box一启动虚拟机就蓝屏(错误代码SYSTEM_SERVICE_EXCEPTION)解决方案 一打开虚拟机电脑就立马蓝屏重启,新建虚拟机也没用,然后就开始 ...

  8. 关于jquery.fileupload结合PHP上传图片的开发用法流程

    这阵子做了一个项目,涉及到了图片上传,以往用的都是uploadify这个插件,感觉它在PC上的使用还是很强大的, 不过最近这个项目涉及到了移动端的上传,其实uploadify也可以,但是他有一个 up ...

  9. asp.net core2.0中网站发布的时候,视图文件不被打包成dll

    项目csproj文件里面加 <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <Target ...

  10. css的双飞翼布局

    双飞翼布局的大概意思就是左右两边的内容是固定的,大小是固定的, 而中间的布局的随着页面的大小变化而自动变化的. 通过代码来解析: 1.四个div,也可以使用section,其中main,left.ri ...