Java中的显示锁 ReentrantLock 和 ReentrantReadWriteLock
在Java1.5中引入了两种显示锁,分别是可重入锁ReentrantLock和可重入读写锁ReentrantReadWriteLock。它们分别实现接口Lock和ReadWriteLock。(注意:synchronized也是可重入锁)
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
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();
}
在此之前我们一直使用的是“内置锁”,也就是synchronized来保证线程安全性的。那么为什么会引入显示锁呢?毕竟synchronized用起来还是十分的简单,好用的(自动获取锁,自动释放锁,简化编程,减少错误)。但是synchronized简单好用的同时,在功能上却不足,存在局限性:
1)synchronized在申请锁如果被阻塞时,无法被中断;而Lock.lockInterruptibly()是可中断的锁;
2)synchronized无法实现轮询锁和限时锁;而使用显示锁的 Lock.tryLock() 配合 sleep() 和 while(true) 可以实现轮询锁;Lock.tryLock(long time, TimeUnit unit)实现了限时锁的功能;
3)另外显示锁的引入了,使我们可以方便实现细粒度的锁定;
4)读写锁的引入能够在读多写少的时提供更好的性能;synchronized和Lock对于“读读”环境也是互斥的;
5)另外显示锁,是我们可以使用“公平锁”;
但是,显示锁的引入也导致了编程的复杂,容易出错,容易导致没有释放锁。必须要使用try{}finally{}来保证锁被释放掉:
Lock lock = new ReentrantLock();
lock.lock();
try{
// access the resource protected by this lock
}finally{
lock.unlock();
}
if(lock.tryLock()){
try{
// ... ...
}finally{
lock.unlock();
}
}
要使用公平锁,需要传入参数:true,我们看一下他们的构造函数:
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
} /**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
默认的 new ReentrantLock(); 获得的是非公平锁。new ReentrantLock(true); 获得的才是公平锁。
所谓“公平锁”是指多个线程在等待同一个锁时,按照申请的先后顺序排队,先申请的线程先获得该锁。不允许插队。但是因为“公平锁”会导致过多的线程上下文切换,从而性能不好。所以一般使用非公平锁。
synchronized 和 ReentrantLock 在“同步”的功能上是等价的。性能方面在java1.6之后也是相似的。在java1.5中显示锁有优势。
所谓的“可重入锁”,是指同一个线程在已经获得了一个对象的锁时,可以再次获得该对象上的锁,不会阻塞。实现原理是,在ReentrantLock中保存了锁的拥有者 owner 和 锁被获取的次数。
总结:
内置锁synchronized,具有简单,好用,不易出错等优点,但是在功能方面有缺陷,不灵活;而显示锁ReentrantLock功能强大,十分灵活,但是编程容易出错。性能方面在java1.6之后两者差别很小,所以在一般情况下,我们会使用内置锁synchronized,只有在synchronized不能满足我们的功能需求时,才会使用显示锁ReentrantLock。
Java中的显示锁 ReentrantLock 和 ReentrantReadWriteLock的更多相关文章
- 多线程并发编程之显示锁ReentrantLock和读写锁
在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是 ...
- Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等
Java 中15种锁的介绍 Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等,在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类 ...
- Java中的各种锁--分类总结
前言 本文需要具备一定的多线程基础才能更好的理解. 学习java多线程时,最头疼的知识点之一就是java中的锁了,什么互斥锁.排它锁.自旋锁.死锁.活锁等等,细分的话可以罗列出20种左右的锁,光是看着 ...
- Java 中的各种锁和 CAS + 面试题
Java 中的各种锁和 CAS + 面试题 如果说快速理解多线程有什么捷径的话,那本文介绍的各种锁无疑是其中之一,它不但为我们开发多线程程序提供理论支持,还是面试中经常被问到的核心面试题之一.因此下面 ...
- Java中15种锁的介绍
作者:搜云库技术团队 原文:https://segmentfault.com/a/1190000017766364 1. Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观 ...
- 分门别类总结Java中的各种锁,让你彻底记住
概念 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁.有可能,会造成优先级反转或者饥 ...
- 轻松学习java可重入锁(ReentrantLock)的实现原理
转载自https://blog.csdn.net/yanyan19880509/article/details/52345422,(做了一些补充) 前言 相信学过java的人都知道 synchroni ...
- java 可重入锁ReentrantLock的介绍
一个小例子帮助理解(我们常用的synchronized也是可重入锁) 话说从前有一个村子,在这个村子中有一口水井,家家户户都需要到这口井里打水喝.由于井水有限,大家只能依次打水.为了实现家家有水喝,户 ...
- 轻松学习java可重入锁(ReentrantLock)的实现原理(转 图解)
前言 相信学过java的人都知道 synchronized 这个关键词,也知道它用于控制多线程对并发资源的安全访问,兴许,你还用过Lock相关的功能,但你可能从来没有想过java中的锁底层的机制是怎么 ...
随机推荐
- sed之打印特定行与连续行
接分号,表示打印特定行,如下命令只会打印出第一行与第十行 sed -n '1p;10p' test.txt 接逗号,表达连续的行娄,如下命令打印出第一行到第十行 sed -n '1,10p' tes ...
- 6/20 sprint3 看板和燃尽图的更新
- JS 将一段文本 每个英文首字母大写
function replaceStr(str){ // 正则法 str = str.toLowerCase(); var reg = /\b(\w)|\s(\w)/g; // \b判断边界\s判断空 ...
- MVC知识点01
1:母版页都 放在View/Shared里面,而且全部的视图页面都可以去用母板页. **母板的应用要用到嵌套,@RenderBody();将别的网页的内容全部显示在此处,它就相当于一个占位符. 2:架 ...
- 2015年百度之星初赛(1) --- F 矩形面积
矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少. Input 第一行一个正整数 T, ...
- ASP.NET 使用AJAX让GridView的数据行显示提示框(ToolTip)
介绍ASP.NET AJAX可以使你的web应用程序具有更丰富的功能和更多的用户响应. 本文中,我将演示如何通过ASP.NET AJAX的帮助,给像GridView这样的数据绑定控件的数据行增加pop ...
- C#递归题目代码
一列数的规则如下: 1.1.2.3.5.8.13.21.34...... 求第30位数是多少, 用递归算法实现. 代码: public class MainClass { public static ...
- 自己通过Cygwin编译的windows下的redis3.2.6
采用方法:https://my.oschina.net/maxid/blog/186506 方法中在3.2.6未找到src/redis.h文件 未修改 方法中 /deps/hiredis/net.c ...
- 四项技术 助你提高SQL Server的性能
有时,为了让应用程序运行得更快,所做的全部工作就是在这里或那里做一些很小调整.但关键在于确定如何进行调整!迟早您会遇到这种情况:应用程序中的 SQL 查询不能按照您想要的方式进行响应.它要么不返回数据 ...
- jQuery $.extend() 和 $.fn.extend() 用法
http://blog.csdn.net/xuemoyao/article/details/19021659