Java Concurrency - ReentrantLock
ReentrantLock 是可重入的互斥锁,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。
ReentrantLock 将由最近成功获得锁,并且还没有释放该锁的线程所拥有。当锁没有被另一个线程所拥有时,调用 lock 方法的线程将成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。
此类的构造方法接受一个可选的 fairness 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁是可用的,此方法就可以获得成功。
建议在调用 lock 方法后总是立即接着使用 try 块。典型的代码如下:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
除了实现 Lock 接口,此类还定义了 isLocked 和 getLockQueueLength 方法,以及一些相关的 protected 访问方法,这些方法对检测和监视可能很有用。
该类的序列化与内置锁的行为方式相同:一个反序列化的锁处于解除锁定状态,不管它被序列化时的状态是怎样的。
ReentrantLock 的方法
getHoldCount()
查询当前线程保持此锁的次数。
对于与解除锁操作不匹配的每个锁操作,线程都会保持一个锁。
保持计数信息通常只用于测试和调试。例如,如果不应该使用已经保持的锁进入代码的某一部分,则可以声明如下:
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert lock.getHoldCount() == 0;
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}
isHeldByCurrentThread()
查询当前线程是否保持此锁。
与内置监视器锁的 Thread.holdsLock(java.lang.Object) 方法类似,此方法通常用于调试和测试。例如,只在保持某个锁时才应调用的方法可以声明如下:
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert lock.isHeldByCurrentThread();
// ... method body
}
}
还可以用此方法来确保某个重入锁是否以非重入方式使用的,例如:
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert !lock.isHeldByCurrentThread();
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}
isLocked()
查询此锁是否由任意线程保持。此方法用于监视系统状态,不用于同步控制。
isFair()
如果此锁的公平设置为 true,则返回 true。
getOwner()
返回目前拥有此锁的线程,如果此锁不被任何线程拥有,则返回 null。
hasQueuedThreads()
查询是否有些线程正在等待获取此锁。注意,因为随时可能发生取消,所以返回 true 并不保证有其他线程将获取此锁。此方法主要用于监视系统状态。
hasQueuedThread(Thread thread)
查询给定线程是否正在等待获取此锁。注意,因为随时可能发生取消,所以返回 true 并不保证此线程将获取此锁。此方法主要用于监视系统状态。
getQueueLength()
返回正等待获取此锁的线程估计数。该值仅是估计的数字,因为在此方法遍历内部数据结构的同时,线程的数目可能动态地变化。此方法用于监视系统状态,不用于同步控制。
getQueuedThreads()
返回一个 collection,它包含可能正等待获取此锁的线程。因为在构造此结果的同时实际的线程池可能动态地变化,所以返回的 collection 仅是尽力的估计值。所返回 collection 中的元素没有特定的顺序。
hasWaiters(Condition condition)
查询是否有些线程正在等待与此锁有关的给定条件。注意,因为随时可能发生超时和中断,所以返回 true 并不保证将来某个 signal 将唤醒线程。此方法主要用于监视系统状态。
getWaitQueueLength(Condition condition)
返回等待与此锁相关的给定条件的线程估计数。注意,因为随时可能发生超时和中断,所以只能将估计值作为实际等待线程数的上边界。此方法用于监视系统状态,不用于同步控制。
getWaitingThreads(Condition condition)
返回一个 collection,它包含可能正在等待与此锁相关给定条件的那些线程。因为在构造此结果的同时实际的线程池可能动态地变化,所以返回 collection 的元素只是尽力的估计值。所返回 collection 中的元素没有特定的顺序。
Java Concurrency - ReentrantLock的更多相关文章
- 《Java Concurrency》读书笔记,使用JDK并发包构建程序
1. java.util.concurrent概述 JDK5.0以后的版本都引入了高级并发特性,大多数的特性在java.util.concurrent包中,是专门用于多线并发编程的,充分利用了现代多处 ...
- Java之ReentrantLock公平锁和非公平锁
在Java的ReentrantLock构造函数中提供了两种锁:创建公平锁和非公平锁(默认).代码如下: public ReentrantLock() { sync = new NonfairSync( ...
- 深入浅出 Java Concurrency (35): 线程池 part 8 线程池的实现及原理 (3)[转]
线程池任务执行结果 这一节来探讨下线程池中任务执行的结果以及如何阻塞线程.取消任务等等. 1 package info.imxylz.study.concurrency.future;2 3 publ ...
- 深入浅出 Java Concurrency (33): 线程池 part 6 线程池的实现及原理 (1)[转]
线程池数据结构与线程构造方法 由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构.图1描述了这种数据结构. 图1 Thre ...
- Java Concurrency in Practice 读书笔记 第十章
粗略看完<Java Concurrency in Practice>这部书,确实是多线程/并发编程的一本好书.里面对各种并发的技术解释得比较透彻,虽然是面向Java的,但很多概念在其他语言 ...
- Java Concurrency - 浅析 CountDownLatch 的用法
The Java concurrency API provides a class that allows one or more threads to wait until a set of ope ...
- Java Concurrency - 浅析 CyclicBarrier 的用法
The Java concurrency API provides a synchronizing utility that allows the synchronization of two or ...
- Java Concurrency - 浅析 Phaser 的用法
One of the most complex and powerful functionalities offered by the Java concurrency API is the abil ...
- Java Concurrency - 线程执行器
Usually, when you develop a simple, concurrent-programming application in Java, you create some Runn ...
随机推荐
- Nginx应用案例分享:压力测试
在运维工作中,压力测试是一项非常重要的工作.比如在一个网站上线之前,能承受多大访问量.在大访问量情况下性能怎样,这些数据指标好坏将会直接影响用户体验. 但是,在压力测试中存在一个共性,那就是压力测试的 ...
- ASP.NET Web Form和MVC中防止F5刷新引起的重复提交问题
转载 http://www.cnblogs.com/hiteddy/archive/2012/03/29/Prevent_Resubmit_When_Refresh_Reload_In_ASP_NET ...
- FPGA高级设计——时序分析和收敛(转)
何谓静态时序分析(Static Timing Analysis,简称STA)? 它可以简单的定义为:设计者提出一些特定的时序要求(或者说是添加特定的时序约束),套用特定的时序模型,针对特定的电路进行分 ...
- C#一些知识点:委托和事件的区别
在C#中,委托和事件是比较容易混淆的两个知识点,本篇博客就记录一下委托和事件之间的区别. 定义上的区别 委托:委托实际上是一个类,用来表示一个函数,可以理解为C++中的函数指针. 事件:事件是一个修饰 ...
- .NET的Snk使用方法
保护你Asp.Net生成的DLL和Code不被别人反编译 大家做项目开发一般都是分层的,比如UI层,业务层,数据访问层.业务层引用数据访问层的DLL(比如 dataAccess.dll),并使用da ...
- ACE的包装器
ACE大量运用包装器模式,以期改变面向过程的系统API可视性以及错误处理较难的情况 包装器在若干场合能极大简化代码量,甚至是编码过程 比如ACE_Thread_Mutex 对象创建会自动初始化,很开心 ...
- 如何彻底隐藏iOS7应用的status bar
用xcode5开发新的iOS游戏,发现一个坑爹的现象,虽然我已经在info.plist里面把Status bar is initially hidden设置成了YES,但在设备上一跑还是看到丑陋的st ...
- 推荐一个CodeProject上的SlideForm控件
CodeProject有一篇文章介绍了怎么实现一个SlideForm,非常不错,收藏在此. http://www.codeproject.com/KB/dialog/csslideform.aspx ...
- iOS 使用compare 进行对比
compare 是 NSString 中的一个方法,这个方法是将字符串 按照 ACSII码表来进行对比. NSString *num1 = @"5.2.0"; NSString * ...
- php 建立类POST/GET 的HTTP请求
1.第一种利用fsock的方式来建立类POST的请求. <?php $srv_ip = '192.168.1.5';//你的目标服务地址. $srv_port = 80;//端口 $url = ...