JUC 一 ReentrantReadWriteLock
java.util.concurrent.locks
ReentrantLock是独占锁,一种相对比较保守的锁策略,在这种情况下任何“读/读”、“读/写”、“写/写”操作都不能同时发生
ReentrantReadWriteLock读写锁内部又分为读锁和写锁,读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
在读锁和写锁的获取过程中支持中断 。Condition只有在写锁中用到(读锁是不支持Condition)
简介
一个线程要想同时持有写锁和读锁,必须先获取写锁再获取读锁;写锁可以“降级”为读锁;读锁不能“升级”为写锁。
线程进入读锁的前提条件(在线程持有读锁的情况下,该线程不能取得写锁):
- 没有其他线程的写锁
线程进入写锁的前提条件( 在线程持有写锁的情况下,该线程可以继续获取读锁):
- 没有其他线程的读锁
- 没有其他线程的写锁
读写锁有以下三个重要的特性:
(1)公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
(2)重进入:读锁和写锁都支持线程重进入。
(3)锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。
基本方法
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable {}
ReentrantReadWriteLock实现了接口ReadWriteLock,该接口提供了两个方法,一个用于获取读锁,另一个用于获取写锁:
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading
*/
Lock readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing
*/
Lock writeLock();
}
ReentrantReadWriteLock
//支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平
public ReentrantReadWriteLock() {
this(false);
}
public ReentrantReadWriteLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
readerLock = new ReadLock(this);
writerLock = new WriteLock(this);
}
public int getReadLockCount():当前读锁被获取的次数,但不是占用该锁的线程数,也就是说,一个线程如果n次获取该锁,该方法返回n,而不是1。
public int getReadHoldCount():当前线程获取读锁的次数。
public boolean isWriteLocked():判断写锁是否被获取。
public int getWriteHoldCount():当前线程获取写锁的次数。
ReadLock
public static class ReadLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -5992448646407690164L;
//持有的AQS对象
private final Sync sync;
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
//获取共享锁
public void lock() {
sync.acquireShared(1);
}
//获取共享锁(响应中断)
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
//尝试获取共享锁
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
//释放锁
public void unlock() {
sync.releaseShared(1);
}
//新建条件
public Condition newCondition() {
throw new UnsupportedOperationException();
}
public String toString() {
int r = sync.getReadLockCount();
return super.toString() +
"[Read locks = " + r + "]";
}
}
示例
public class ReadWriteLock {
static ReadWriteLock lock=new ReentrantReadWriteLock();
static Lock read=lock.readLock();
static Lock write=lock.writeLock();
static HashMap<String, Object> map=new HashMap<String, Object>();
static Object get(String key){
read.lock();
try {
return map.get(key);
} finally {
read.unlock();
}
}
static void put(String key,Object value){
write.lock();
try {
map.put(key, value);
} finally {
write.unlock();
}
}
static void clear(){
write.lock();
try {
map.clear();
} finally {
write.unlock();
}
}
}
锁降级示例
锁降级是指把持住(当前拥有的)写锁,再获取到读锁,随后释放(先前拥有的)写锁的过程。
static Object putAndget(String key,Object value){
write.lock();
try {
read.lock();
map.put(key, value);
} finally {
write.unlock();
}
try {
return map.get(key);
} finally {
read.unlock();
}
}
JUC 一 ReentrantReadWriteLock的更多相关文章
- 6.JUC之ReentrantReadWriteLock
一.概述: Java纪年1.5年,ReentrantReadWriteLock诞生于JUC,此后,国人一般称它为读写锁.人如其名,他就是一个可重入锁,同时他还是一个读写锁 a)跟ReentrantLo ...
- 最强Java并发编程详解:知识点梳理,BAT面试题等
本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
- Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock
概要 Java的JUC(java.util.concurrent)包中的锁包括"独占锁"和"共享锁".在“Java多线程系列--“JUC锁”02之 互斥锁Ree ...
- Java - "JUC" ReentrantReadWriteLock
Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock ReadWriteLock 和 ReentrantReadWriteLock介绍 ReadWriteLo ...
- 【Java并发】JUC—ReentrantReadWriteLock有坑,小心读锁!
好长一段时间前,某些场景需要JUC的读写锁,但在某个时刻内读写线程都报超时预警(长时间无响应),看起来像是锁竞争过程中出现死锁(我猜).经过排查项目并没有能造成死锁的可疑之处,因为业务代码并不复杂(仅 ...
- 【JUC】JDK1.8源码分析之ReentrantReadWriteLock(七)
一.前言 在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁 ...
- 【JUC】JDK1.8源码分析之ReentrantReadWriteLock
重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服务不存在数据竞争问题,如果一个线程在读 ...
- JUC——线程同步锁(ReentrantReadWriteLock读写锁)
读写锁简介 所谓的读写锁值得是两把锁,在进行数据写入的时候有一个把“写锁”,而在进行数据读取的时候有一把“读锁”. 写锁会实现线程安全同步处理操作,而读锁可以被多个对象读取获取. 读写锁:ReadWr ...
- 【JUC源码解析】ReentrantReadWriteLock
简介 ReentrantReadWriteLock, 可重入读写锁,包括公平锁和非公平锁,相比较公平锁而言,非公平锁有更好的吞吐量,但可能会出现队列里的线程无限期地推迟一个或多个读线程或写线程的情况, ...
随机推荐
- 第三章 k8s的node节点配置
一.修改主机名 hostnamectl set-hostname xxx 二.修改hosts文件vim /etc/hosts 三.将写好的hosts文件拷贝到其他节点 scp /etc/hosts r ...
- Lenovo E42-80安装Linux的注意事项
Lenovo E42-80安装Linux的注意事项 https://www.cnblogs.com/dylanchu/p/9750760.html 1. 用U盘做个liveCD While makin ...
- Rikka with Competition
Rikka with Competition 给出一个大小为n的集合\(\{a_i\}\),每次从集合中随机挑出一对数\(a_i,a_j\),如果\(|a_i-a_j|>K\),那么从集合中删掉 ...
- thinkphp REST
REST介绍 REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性.REST提出了一些设 ...
- noip2002 普及组 过河卒
题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过 ...
- mac os 下安装mysql
在 http://dev.mysql.com/downloads/mysql/ 选择下载mysql 注册并选择相应的版本后,得到下载链接:: wget http://dev.mysql.com/get ...
- 如何将已经下造好的apk安装到eclipse本身的模拟器里面
参考资料:http://blog.csdn.net/zzp_403184692/article/details/7948212 在项目开发中,想将上一个版本的手机软件放到模拟器里面进行测试,但是如何操 ...
- (转)Linux环境进程间通信----系统 V 消息队列列
转:http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.作为早期unix通 ...
- myeclipse 启动卡住的解决办法
myeclipse 启动卡住的解决办法 今天启动myeclipse突然卡住,CPU一直占用,启动任务管理器强制关闭.重启myeclipse,重启电脑都不能够解决. 上网查找,在工程路径(工作空间的路径 ...
- hexo next博客之无敌之舒服之美妙之轻松之发布博客(mweb,github自主开发插件)
文章目录 **前言:** 具体用法 **mweb for mac** 注意 **github插件下载** 个人博客:https://mmmmmm.me 源码:https://github.com/da ...