java.util.concurrent.locks

ReentrantLock是独占锁,一种相对比较保守的锁策略,在这种情况下任何“读/读”、“读/写”、“写/写”操作都不能同时发生

ReentrantReadWriteLock读写锁内部又分为读锁和写锁,读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。

在读锁和写锁的获取过程中支持中断 。Condition只有在写锁中用到(读锁是不支持Condition)

简介

一个线程要想同时持有写锁和读锁,必须先获取写锁再获取读锁;写锁可以“降级”为读锁;读锁不能“升级”为写锁。

线程进入读锁的前提条件(在线程持有读锁的情况下,该线程不能取得写锁):

  1. 没有其他线程的写锁

线程进入写锁的前提条件( 在线程持有写锁的情况下,该线程可以继续获取读锁):

  1. 没有其他线程的读锁
  2. 没有其他线程的写锁

读写锁有以下三个重要的特性:

(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的更多相关文章

  1. 6.JUC之ReentrantReadWriteLock

    一.概述: Java纪年1.5年,ReentrantReadWriteLock诞生于JUC,此后,国人一般称它为读写锁.人如其名,他就是一个可重入锁,同时他还是一个读写锁 a)跟ReentrantLo ...

  2. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  3. Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock

    概要 Java的JUC(java.util.concurrent)包中的锁包括"独占锁"和"共享锁".在“Java多线程系列--“JUC锁”02之 互斥锁Ree ...

  4. Java - "JUC" ReentrantReadWriteLock

    Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock ReadWriteLock 和 ReentrantReadWriteLock介绍 ReadWriteLo ...

  5. 【Java并发】JUC—ReentrantReadWriteLock有坑,小心读锁!

    好长一段时间前,某些场景需要JUC的读写锁,但在某个时刻内读写线程都报超时预警(长时间无响应),看起来像是锁竞争过程中出现死锁(我猜).经过排查项目并没有能造成死锁的可疑之处,因为业务代码并不复杂(仅 ...

  6. 【JUC】JDK1.8源码分析之ReentrantReadWriteLock(七)

    一.前言 在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁 ...

  7. 【JUC】JDK1.8源码分析之ReentrantReadWriteLock

    重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服务不存在数据竞争问题,如果一个线程在读 ...

  8. JUC——线程同步锁(ReentrantReadWriteLock读写锁)

    读写锁简介 所谓的读写锁值得是两把锁,在进行数据写入的时候有一个把“写锁”,而在进行数据读取的时候有一把“读锁”. 写锁会实现线程安全同步处理操作,而读锁可以被多个对象读取获取. 读写锁:ReadWr ...

  9. 【JUC源码解析】ReentrantReadWriteLock

    简介 ReentrantReadWriteLock, 可重入读写锁,包括公平锁和非公平锁,相比较公平锁而言,非公平锁有更好的吞吐量,但可能会出现队列里的线程无限期地推迟一个或多个读线程或写线程的情况, ...

随机推荐

  1. Java高并发网络编程(二)BIO

    一.阻塞 服务器端 public class BIOServer { public static void main(String[] args) throws Exception { ServerS ...

  2. 数据结构(c语言版,严蔚敏)第3章栈和队列

    第3章栈和队列

  3. Shiro学习(21)授予身份及切换身份

    在一些场景中,比如某个领导因为一些原因不能进行登录网站进行一些操作,他想把他网站上的工作委托给他的秘书,但是他不想把帐号/密码告诉他秘书,只是想把工作委托给他:此时和我们可以使用Shiro的RunAs ...

  4. 【LeetCode 9】回文数

    题目链接 [题解] 还是要注意,取反的时候,-2^31 取反的话会爆掉Int..(因为int的正数最多到2^31-1) [代码] class Solution { public: bool isPal ...

  5. Android中如何搭建一个WebServer

    今天终于把老大交代的任务搞完了,感觉收获挺多的,所以就写一篇来记录一下吧,首先还是来看一下,老大们的需求 需求: 希望移动端的用户标识(IMEI)和HTML页面的用户标识(Cookie)连接起来,其中 ...

  6. [NOIP模拟测试7]visit 题解(组合数学+CRT+Lucas定理)

    Orz 因为有T的限制,所以不难搞出来一个$O(T^3)$的暴力dp 但我没试 据说有30分? 正解的话显然是组合数学啦 首先$n,m$可能为负,但这并没有影响, 我们可以都把它搞成正的 即都看作向右 ...

  7. Jeecg集成Swagger-ui

    <context:component-scan base-package="springfox"/> <bean class="org.jeecgfra ...

  8. VScode Python no module的解决方法

    在lauch.json中,修改 "env": {}为 "env": {"PYTHONPATH":"${workspaceRoot} ...

  9. python之pypinyin

    python 汉字拼音库 pypinyin 这个库还是很好用的,这个库还是很简单的,中文注解,下面是源码,看注释就可以大致明白方法的意思 #!/usr/bin/env python # -*- cod ...

  10. HTML5字体、伪元素、背景

    1.字体样式: 选择器  { font:font-style  font-weight  font-size / line-height   font-family:} 例:p { font: ita ...