介绍

DK1.5之后,提供了读写锁ReentrantReadWriteLock,读写锁维护了一对锁:一个读锁,一个写锁。通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。

源码定义

/*
* <p>This lock supports a maximum of 65535 recursive write locks
* and 65535 read locks. Attempts to exceed these limits result in
* {@link Error} throws from locking methods.
*
* @since 1.5
* @author Doug Lea
*/
public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable {
private static final long serialVersionUID = -6992448646407690164L;
/** Inner class providing readlock */
private final ReentrantReadWriteLock.ReadLock readerLock;
/** Inner class providing writelock */
private final ReentrantReadWriteLock.WriteLock writerLock;
/** Performs all synchronization mechanics */
final Sync sync;
...
}

code

public class ReentrantReadWriteLockTest {
ReentrantReadWriteLock lock;
private ReentrantReadWriteLock.ReadLock readLock;
private ReentrantReadWriteLock.WriteLock writeLock; private ReentrantReadWriteLockTest() {
lock = new ReentrantReadWriteLock();
readLock = lock.readLock();
writeLock = lock.writeLock();
} public void read() {
try {
readLock.lock();
System.out.println(Thread.currentThread().getName() + " 开始读了。。。");
Thread.sleep(3000);
}catch (InterruptedException e) { }finally {
System.out.println(Thread.currentThread().getName() + " 读结束了。。。");
readLock.unlock();
}
} public void write() {
try {
writeLock.lock();
System.out.println(Thread.currentThread().getName() + " 开始写了。。。");
Thread.sleep(3000);
} catch (InterruptedException e) { } finally {
System.out.println(Thread.currentThread().getName() + " 写完了。。。");
writeLock.unlock();
}
}
}

测试1

 public static void main(String[] args) {
final ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
test.read(); }
}, "ReadThread1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
test.read();
}
}, "ReadThread2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
test.write();
}
}, "WriteThread1");
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
test.write();
}
}, "WriteThread4"); t1.start();
t2.start();
}

输出

ReadThread1 开始读了。。。
ReadThread2 开始读了。。。
ReadThread1 读结束了。。。
ReadThread2 读结束了。。。

结论:读读共享  

测试2

t2.start();
t3.start();

输出

ReadThread2 开始读了。。。
ReadThread2 读结束了。。。
WriteThread1 开始写了。。。
WriteThread1 写完了。。。

结论:读写互斥

测试3

t4.start();
t3.start();

输出

WriteThread4 开始写了。。。
WriteThread4 写完了。。。
WriteThread1 开始写了。。。
WriteThread1 写完了。。。

结论:写写互斥

注意:新生成变量时,要用final修饰

final ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();

原因:从内部类访问本地变量,本地变量要被声明为final类型

读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥的更多相关文章

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

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

  2. [图解Java]读写锁ReentrantReadWriteLock

    图解ReentrantReadWriteLock 如果之前使用过读写锁, 那么可以直接看本篇文章. 如果之前未使用过, 那么请配合我的另一篇文章一起看:[源码分析]读写锁ReentrantReadWr ...

  3. Java并发(十):读写锁ReentrantReadWriteLock

    先做总结: 1.为什么用读写锁 ReentrantReadWriteLock? 重入锁ReentrantLock是排他锁,在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服 ...

  4. 轻松掌握java读写锁(ReentrantReadWriteLock)的实现原理

    转载:https://blog.csdn.net/yanyan19880509/article/details/52435135 前言 前面介绍了java中排它锁,共享锁的底层实现机制,本篇再进一步, ...

  5. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  6. 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

    ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...

  7. 十五、读写锁ReentrantReadWriteLock

    一.简介 有时候我们对资源的修改操作非常地少,但是读取的频率却很高.如果采用一般的互斥锁,那么大量的读取操作也需要做等待.基于读写分离的思想,我们可以使用JDK的读写锁来处理这种情况. 1)读读不互斥 ...

  8. 深入浅出 Java Concurrency (13): 锁机制 part 8 读写锁 (ReentrantReadWriteLock) (1)

      从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock). ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念.前面的章节中一 ...

  9. 【原创】读写锁ReentrantReadWriteLock原理分析(一)

    Java里面真正意义的锁并不多,其实真正的实现Lock接口的类就三个,ReentrantLock和ReentrantReadWriteLock的两个内部类(ReentrantReadWriteLock ...

随机推荐

  1. Redis各种数据类型的应用场景

    redis是一种key values形式的非关系型数据库,通过内存存储,也可以把数据持久化到本地文件中. redis支持丰富的数据类型,String,list,set,zset,hash,下面说一下各 ...

  2. Catalog

      Java SE EE| Hibernate | Struts2Spring/SpringMVC | MyBatis C# Python PHP C/C++ | STL 汇编语言           ...

  3. ADO.NET MSSSQLServer 操作简要总结

    1).数据库操作首先应该是链接,链接的方式有多种,不论怎样实现最终都是把链接字符串赋值给实现了 继承自DbConnection 类的SqlConnection类实例的ConnectionString属 ...

  4. p112 the podocyte

    正常人尿液只有一很少的蛋白质.尿蛋白特别是白蛋白的出现,是肾小球疾病的重要特征,也是众多肾脏疾病的关键的诊断标记,包括了统计数据或者说经济效应上都很重要的那些肾病.糖尿病肾病等等.可能没被广泛认识的是 ...

  5. .NET工行E生活接入AES加密算法的吐槽-2018

    工行E生活V2版本AES加密算法 吐槽一下工行的java算法,真的是非标准的,参考了java代码,还参考了php代码终于搞定了. 真的是很坑,很坑.中间还涉及到多重加密之类的,一行行把代码翻译成C#代 ...

  6. java 保证程序安全退出

    以前在开发时只知道依靠数据库事务来保证程序关闭时数据的完整性. 但有些时候一个业务上要求的原子操作,不一定只包括数据库,比如外部接口或者消息队列.此时数据库事务就无能为力了. 这时我们可以依靠java ...

  7. hdu 4069 垃圾数独

    首先dfs给每个格子分一个大的区块 其次套板子就a 我一开始直接在选取行的时候填数独,发现超时 我这一行也就4个元素,找到 x <= 81 的列计算元素位置,81 < x <= 16 ...

  8. maven 本地仓库无法更新到最新版本的jar包

    maven 本地仓库无法更新到最新版本的jar包 描述:maven 本地仓库无法更新最新版的jar包导致项目一直报错 解决:去jar包版本所在目录,删除掉所有红框内文件,重新用ide导入

  9. html快速编写

    1. 嵌套操作---------- 子操作: > div>ul>li <div> <ul> <li></li> </ul> ...

  10. JavaScript(变量、作用域和内存问题)

    JavaScript是一个变量松散型的语言.(不像Java一样强类型语言.) JavaScript变量包括两种:基本类型(简单的数据段)和引用类型(对象). 一.基本数据类型(5种) Undefine ...