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中的锁底层的机制是怎么 ...
随机推荐
- HT图形组件设计之道(四)
在<HT图形组件设计之道(二)>我们展示了HT在2D图形矢量的数据绑定功能,这种机制不仅可用于2D图形,HT的通用组件甚至3D引擎都具备这种数据绑定机制,此篇我们将构建一个3D飞机模型,展 ...
- thread_Disruptor
转自 知乎 https://zhuanlan.zhihu.com/p/21355046 order从client端传入,decode后进行matching,一旦存在可成交的价格,就要publish到t ...
- 数论 - 欧拉函数模板题 --- poj 2407 : Relatives
Relatives Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11372 Accepted: 5544 Descri ...
- .net4.0注册到IIS ,重新注册IIS ,iis注册
IIS和.netfw4.0安装顺序是从前到后,如果不小心颠倒了,无所谓. 打开程序-运行-cmd:输入一下命令重新注册IIS C:\WINDOWS\Microsoft.NET\Framework\v4 ...
- Unity多语言本地化改进版
简介 之前捣鼓过一个通过csv配置游戏多语言支持的小工具,但是发现使用过程中,通过notepad++去进行转码很不方便,并且直接将配置的csv不加密的放在游戏中心里感觉不是很踏实 于是乎~~ 新的方案 ...
- ASP.NET MVC使用input标签上传文件
有些时间学习了,温习一下ASP.NET MVC了.上传文档是在开发过程中,必须撑握的一个功能.以前上传均是使用第三方控件uploadify来实现,今天使使用VS标准标签input 的type=&quo ...
- 【iOS】XcodeColors插件与CocoaLumberjack工具
工欲善其事必先利其器,好的开发者一定是懂得利用工具来提高自己的效率的,Xcode有很多第三方插件可以使用,最近发现一个可以给控制台着色的工具XcodeColors,结合CocoaLumberjack一 ...
- DataSet导出到Excel,并生成文件(C#实现,可合并行和列)
using System; using System.IO; using System.Data; using System.Reflection; using System.Diagnostics; ...
- 用linux遇到的一个死循环
1. 公司的服务器centos,需要通过vpn拨上去: 2. 然后ftp启用了tls加密: 3. 然后ubuntu 12.04 上libgnutls的版本比较新,装的filezilla 3.5.3,怎 ...
- 【GOF23设计模式】责任链模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_责任链模式.公文审批.供应链系统的采购审批.异常链.过滤器和拦截器调用过程 package com.test.chainO ...