ReentrantLock 学习
Java接口Lock有三个实现类:ReentrantLock、ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock。Lock接口提供了比使用synchronized更广泛的锁操作。
ReentrantLock是一个可重入的互斥锁。重入的含义是:当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会被阻塞。但是如果某个线程试图获得一个已经由它自己持有的锁时,这个请求是会成功的。"重入"意味着获取锁的操作的粒度是"线程",而不是"调用"。重入的一种实现方式就是,为每个锁关联一个获取计数值和一个所有者线程。当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取到的计数值置为1.如果同一个线程再次获取这个锁,计数值将被递增,而当线程退出同步代码块时,计数器会相应地递减。当计数值为0时,这个锁将被释放。
对于ReentrantLock锁将由最近成功获得锁,并且没有释放该锁的线程所拥有。当锁没有被另外一个线程所拥有时,调用lock的线程将会成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。
ReentrantLock基础API
lock()获取锁
加锁,如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为1。
如果当前线程之前已经获取到了该锁,则将保持计数加1,并且该方法立即返回。
如果该锁已经被另一个线程保持,则该线程不可被调度(即当前线程处于阻塞状态)直到该线程获取到锁,并且在获取到锁后,将保持计数设置为1。unlock释放锁
试图释放锁。如果当前线程是此锁所有者,则将保持计数减1。如果保持计数器现在为0,则释放该属锁。如果当前线程不是此锁的持有者,则抛出IllegalMonitorStateException。
private Lock lock = new ReentrantLock() ;
public void await() {
try {
lock.lock();//加锁
} finally {
lock.unlock();//释放锁
}
}
- trylock()
仅在调用时锁未被另一个线程保持的情况下,才获取锁。
如果该锁没有被另一个线程保持,并且立即返回 true 值,则将锁的保持计数设置为 1。即使已将此锁设置为使用公平排序策略,但是调用 tryLock() 仍将 立即获取锁(如果有可用的),而不管其他线程当前是否正在等待该锁。在某些情况下,此“闯入”行为可能很有用,即使它会打破公平性也如此。如果希望遵守此锁的公平设置,则使用 tryLock(0, TimeUnit.SECONDS) ,它几乎是等效的(也检测中断)。
如果当前线程已经保持此锁,则将保持计数加 1,该方法将返回 true。
如果锁被另一个线程保持,则此方法将立即返回 false 值。
- tryLock(long timeout, TimeUnit unit)
如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁。
为了使用公平的排序策略,如果其他线程已经获取此锁,并且还有其他线程都在等待该锁,则立刻不会获取一个可用的锁,而公平的和其他线程进行等待锁分配。这与trylock方法相反。如果想使用一个允许闯入公平锁的定时tryLock,那么可以将定时形式和不定时形式组合在一起使用:
if(lock.tryLock() || lock.tryLock(timeout,uniy)) {
//.....
}
- lockInterruptibly
如果当前线程未被中断,则获取锁。
- 如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为1。
- 如果该线程已经保持此锁,则将保持计数加1,并且该方法立即返回。
- 如果该锁已经被其他线程保持,则等待;等待过程中,如果被其他线程打算,则抛出InterrupterException,并且中断该线程。
- 在具体业务里,因为此方法是一个显示中断点,所以要优先考虑响应中断,而不是响应锁的普通获取或重入获取。
总结
- lock --> 无限锁 调用后一直阻塞直到获得锁。
- tryLock --> 拿到锁就返回true,不然就返回false;带有时间限制的tryLock(),拿不到锁,就等待一段时间,超时返回false。与while配合,可以实现轮询锁。
- lockInterruptibly --> 调用后如果没有获取到锁会一直阻塞,阻塞过程中会接受中断信号。
参考原文地址
ReentrantLock 学习的更多相关文章
- ReentrantLock学习
对于并发工作,你需要某种方式来防止两个任务访问相同的资源,至少在关键阶段不能出现这种冲突情况.防止这种冲突的方法就是当资源被一个任务使用时,在其上加锁.在前面的文章--synchronized学习中, ...
- java并发之ReentrantLock学习理解
简介 java多线程中可以使用synchronized关键字来实现线程间同步互斥,但在jdk1.5中新增加了ReentrantLock类也能实现同样的效果,并且在扩展功能上也更加强大,比如具有嗅探锁定 ...
- ReentrantLock 学习笔记
有篇写的很不错的博客:https://blog.csdn.net/aesop_wubo/article/details/7555956 基于JDK1.8 参考着看源码 ,弄清楚lock()和un ...
- ReentrantLock学习笔记
参考:https://www.jianshu.com/p/4358b1466ec9 前言: 先来想象一个场景:手把手的进行锁获取和释放,先获得锁A,然后再获取锁B,当获取锁B后释放锁A同时获取锁C,当 ...
- Java并发编程总结3——AQS、ReentrantLock、ReentrantReadWriteLock(转)
本文内容主要总结自<Java并发编程的艺术>第5章——Java中的锁. 一.AQS AbstractQueuedSynchronizer(简称AQS),队列同步器,是用来构建锁或者其他同步 ...
- Java并发编程总结3——AQS、ReentrantLock、ReentrantReadWriteLock
本文内容主要总结自<Java并发编程的艺术>第5章——Java中的锁. 一.AQS AbstractQueuedSynchronizer(简称AQS),队列同步器,是用来构建锁或者其他同步 ...
- ThreadLocal使用和原理简析
1. 解决共享资源冲突 对于并发工作,需要某种方式来防止两个任务同时访问相同的资源,至少在关键阶段不能出现这种冲突情况. 方法之一就是当资源被一个任务使用时,在其上加锁.第一个访问某项资源的任务必须锁 ...
- JUC之AQS
AbstractQueuedSynchronizer(AQS) AQS是并发容器里的同步器,从jdk1.5开始引入了并发包,java.util.concurrent,提供了一个基于first in f ...
- ReentrantLock原理学习
上文我们学习了ReentrantLock的基本用法,在最后我们留下了一个问题,ReentrantLock获取的锁是什么锁呢?本文我们就从源码的角度来一探究竟.本文涉及到的源码对应JDK版本为1.8. ...
随机推荐
- CodeForces - 50A Domino piling (贪心+递归)
CodeForces - 50A Domino piling (贪心+递归) 题意分析 奇数*偶数=偶数,如果两个都为奇数,最小的奇数-1递归求解,知道两个数都为1,返回0. 代码 #include ...
- 解决jsp两种提交方式乱码 的方法
解决中文乱码 ---post提交方式 需要在处理页面添加request.setCharacterEncoding("utf-8"); 制定请求的编码,调用一下request.ge ...
- ContestHunter暑假欢乐赛 SRM 01 - 儿童节常数赛 爆陵记
最后15min过了两题...MDZZ 果然是不适合OI赛制啊...半场写完三题还自信满满的,还好有CZL报哪题错了嘿嘿嘿(这算不算犯规了(逃 悲惨的故事*1....如果没有CZL的话T1 10分 悲惨 ...
- Matrix.(POJ-2155)(树状数组)
题目是让每次对一个子矩阵进行翻转(0变1,1变0), 然后有多次询问,询问某个点是0还是1 这题可以用二维的树状数组来解决,考虑传统的树状数组是改变某个点,然后查询某一段, 而这个题是改变某一段,查询 ...
- mysql的时间函数整理
转:这里总结的非常齐全: http://fengbin2005.iteye.com/blog/1999763 Mysql时间函数 对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描 ...
- 题解 【luoguP1967 NOIp提高组2013 货车运输】
题目链接 题解 题意 给你一个无向图,求两个点之间的一条路径,使路径上的最小值最大 算法:Kruskal最大生成树+倍增lca 分析 首先容易知道,答案一定在该图的最大生成树上 之后问题便转换成了树上 ...
- matlab求一个矩阵中各元素出现的个数(归一化)
function [m,n] = stamatrix(a) %网上找到的方法,感觉很巧妙 x=a(:); x=sort(x); d=diff([x;max(x)+1]); count = diff(f ...
- 移动端1px边框问题
用于手机端受dpr的影响,实际开发中,PC端和移动端展示的效果不太一样,往往在PC端显示的是1px,移动端常常是偏粗一些. 解决办法: 主要是用到伪类及缩放.在需要画边框的元素上,设置一个伪类,它的伪 ...
- 基于html5的动画库,非svg和canvas
基于html5的动画库,非svg和canvas https://greensock.com/docs/#/HTML5/GSAP/TweenLite/
- Docker explainations
What does docker run --link mean, what's the usage? link 是在两个contain之间建立一种父子关系,父container中的web,可以得到子 ...