ReentrantLock的相关方法使用
获取锁定
- void lock():常用获取锁定的方法
- void lockInterruptibly():如果当前线程未被中断,则获取锁定;如果当前线程被中断,则出现异常
- boolean tryLock():调用时锁定未被另一个线程持有的情况下,才会获取该锁定
- boolean tryLock(long timeOut,TimeUnit unit):如果锁定在给定时间内未被另一个线程持有,且当前线程未被中断,则获取该锁定
lock()方法
public class Run {
private ReentrantLock lock = new ReentrantLock();
public void testLock(){
try {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("ThreadName = "+Thread.currentThread().getName()+", i = "+(i+1));
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕,当前时间:"+System.currentTimeMillis());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Run run = new Run();
run.testLock();
Runnable runnable = new Runnable() {
@Override
public void run() {
run.testLock();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
}
----------------------------------------------------console----------------------------------------------------
ThreadName = main, i = 1
ThreadName = main, i = 2
ThreadName = main, i = 3
ThreadName = main, i = 4
ThreadName = main, i = 5
main线程执行完毕,当前时间:1539138509575
ThreadName = A, i = 1
ThreadName = A, i = 2
ThreadName = A, i = 3
ThreadName = A, i = 4
ThreadName = A, i = 5
A线程执行完毕,当前时间:1539138510587
ThreadName = B, i = 1
ThreadName = B, i = 2
ThreadName = B, i = 3
ThreadName = B, i = 4
ThreadName = B, i = 5
B线程执行完毕,当前时间:1539138511587
lockInterruptibly()方法
public class Run2 {
private ReentrantLock lock = new ReentrantLock();
public void testLockInterruptibly(){
try {
lock.lockInterruptibly();
System.out.println("ThreadName = "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(lock.isHeldByCurrentThread()){//查询当前线程是否保持锁定
lock.unlock();
}
}
}
public static void main(String[] args) {
Run2 run2 = new Run2();
Runnable runnable = new Runnable() {
@Override
public void run() {
run2.testLockInterruptibly();
}
};
Thread t1 = new Thread(runnable);
t1.setName("T1");
t1.start();
Thread t2 = new Thread(runnable);
t2.setName("T2");
t2.start();
t2.interrupt();
}
}
----------------------------------------------------console----------------------------------------------------
java.lang.InterruptedException
ThreadName = T1
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at com.qf.test12.t.Run2.testLockInterruptibly(Run2.java:13)
at com.qf.test12.t.Run2$1.run(Run2.java:29)
at java.lang.Thread.run(Thread.java:748)
tryLock()方法
public class Run3 {
private ReentrantLock lock = new ReentrantLock();
public void testTryLock(){//只获取锁定,不释放锁定
if(lock.tryLock()){
System.out.println(Thread.currentThread().getName()+"获得锁");
}else {
System.out.println(Thread.currentThread().getName()+"未获得锁");
}
}
public static void main(String[] args) {
Run3 run3 = new Run3();
Runnable runnable = new Runnable() {
@Override
public void run() {
run3.testTryLock();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
}
----------------------------------------------------console----------------------------------------------------
A获得锁
B未获得锁
tryLock(long timeOut,TimeUnit unit)方法
public class Run3 {
private ReentrantLock lock = new ReentrantLock();
public void testTryLock(){
try {
if(lock.tryLock(3, TimeUnit.SECONDS)){
System.out.println(Thread.currentThread().getName()+"获得锁");
Thread.sleep(4000);//有一个未获得锁
//Thread.sleep(2000);//两个都获得锁
}else {
System.out.println(Thread.currentThread().getName()+"未获得锁");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
public static void main(String[] args) {
Run3 run3 = new Run3();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行,当前时间:"+System.currentTimeMillis());
run3.testTryLock();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
}
----------------------------------------------------console----------------------------------------------------
--------------------Thread.sleep(4000)-------------------
A执行,当前时间:1539141085501
B执行,当前时间:1539141085501
B获得锁
A未获得锁
--------------------Thread.sleep(2000)-------------------
A执行,当前时间:1539141269380
B执行,当前时间:1539141269380
A获得锁
B获得锁
其他常用方法
getXxx方法
- int getHoldCount()方法:查询当前线程保持此锁定的个数,即当前线程调用lock()方法的次数
- int getQueueLength()方法:返回正在等待此锁定的线程估计数
- int getWaitQueueLength(Condition condition)方法:返回等待与此锁定相关的给定条件的线程估计数
hasXxx方法
- boolean hasQueuedThread(Thread thread)方法:查询指定线程是否正在等待获取此锁定
- boolean hasQueuedThreads()方法:查询是否有线程正在等待此锁定
- boolean hasWaiters(Condition condition)方法:查询是否有线程正在等待与此锁定有关的condition条件
isXxx方法
- boolean isFair()方法:判断是不是公平锁
- boolean isHeldByCurrentThread()方法:查询当前线程是否保持此锁定
- boolean isLocked()方法:判断此锁定是否由任意线程保持
Condition的几个方法
- awaitUninterruptibly()方法:调用该方法的前提是,当前线程已经成功获得与该条件对象绑定的重入锁,否则调用该方法时会抛出IllegalMonitorStateException。调用该方法后,结束等待的唯一方法是其它线程调用该条件对象的signal()或signalALL()方法。等待过程中如果当前线程被中断,该方法仍然会继续等待,同时保留该线程的中断状态。
- awaitNanos(long nanosTimeout) 方法:调用该方法的前提是,当前线程已经成功获得与该条件对象绑定的重入锁,否则调用该方法时会抛出IllegalMonitorStateException。nanosTimeout指定该方法等待信号的的最大时间(单位为纳秒)。若指定时间内收到signal()或signalALL()则返回nanosTimeout减去已经等待的时间;若指定时间内有其它线程中断该线程,则抛出InterruptedException并清除当前线程的打断状态;若指定时间内未收到通知,则返回0或负数
- awaitUntil(Date deadline) 方法:适用条件与行为与awaitNanos(long nanosTimeout)完全一样,唯一不同点在于它不是等待指定时间,而是等待由参数指定的某一时刻,等待时间到达前可以被其他线程提前唤醒
ReentrantLock的相关方法使用的更多相关文章
- 通过ReentrantLock源代码分析AbstractQueuedSynchronizer独占模式
1. 重入锁的概念与作用 reentrant 锁意味着什么呢?简单来说,它有一个与获取锁相关的计数器,如果已占有锁的某个线程再次获取锁,那么lock方法中将计数器就加1后就会立刻返回.当释 ...
- 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()
最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...
- 透过ReentrantLock窥探AQS
背景 JDK1.5引入的并发包提供了一系列支持中等并发的类,这些组件是一系列的同步器,几乎任一同步器都可以实现其他形式的同步器,例如,可以用可重入锁实现信号量或者用信号量实现可重入锁.但是,这样做带来 ...
- 基于ReentrantLock的非公平锁理解AQS
AQS AQS概述 AbstractQueuedSynchronizer抽象队列同步器简称AQS,它是实现同步器的基础组件,juc下面Lock的实现以及一些并发工具类就是通过AQS来实现的,这里我 ...
- B9 Concurrent 重入锁(ReentrantLock)
[概述] java.util.concurrent.locks.ReentrantLock 实现 java.util.concurrent.locks.Lock 接口,加锁(lock)和 解锁(unl ...
- ReentrantLock 源码分析以及 AQS (一)
前言 JDK1.5 之后发布了JUC(java.util.concurrent),用于解决多线程并发问题.AQS 是一个特别重要的同步框架,很多同步类都借助于 AQS 实现了对线程同步状态的管理. A ...
- Java读源码之ReentrantLock(2)
前言 本文是 ReentrantLock 源码的第二篇,第一篇主要介绍了公平锁非公平锁正常的加锁解锁流程,虽然表达能力有限不知道有没有讲清楚,本着不太监的原则,本文填补下第一篇中挖的坑. Java读源 ...
- Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)
AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...
- 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock
ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...
随机推荐
- ReactOS 无法显示中文的问题
其实非常简单, 实际上是因为包里面没有中文字体,所以输出文字都是乱码, 去 https://svn.reactos.org/optional/ 这里,下载ttf字体文件, 把字体文件放到源码中 mod ...
- elasticsearch api约定
elasticsearch REST API 使用JSON通过HTTP协议传输. 本约定贯穿整个REST API,除非有特别的说明. 一.多重索引 大多数APIs引用到一个index参数来在多个索引中 ...
- 用python编写排序算法
交换排序 === 冒泡排序,快速排序 插入排序 ===直接插入排序,希尔排序 选择排序 === 简单选择排序,堆排序 归并排序 基数排序 冒泡排序 要点 冒泡排序是一种交换排序. 什么是交换排序呢? ...
- 转载:java面试题(一)
1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...
- 三、SpringBoot项目探究
1.pom文件 父项目 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...
- reduce 好东西
reduce()方法可以搞定的东西,for循环,或者forEach方法有时候也可以搞定,那为啥要用reduce()?这个问题,之前我也想过,要说原因还真找不到,唯一能找到的是:通往成功的道路有很多,但 ...
- Spring 讲解(六)
如何理解 Spring 中的 AOP 一.AOP 的概述 AOP(Aspect Oriented Programming):面向切面编程,通过预编译方式和运行期动态代理来实现程序功能的统一维护的一种技 ...
- Delphi 正则表达式之TPerlRegEx
官方网站: http://www.regular-expressions.info/delphi.html 直接下载: http://www.regular-expressions.info/down ...
- BZOJ 1006: [HNOI2008]神奇的国度(弦图)
传送门 解题思路 弦图就是图中任意一个大小\(>=4\)的环至少存在一条两个节点不相邻的边,这样的图称为弦图,弦图有许多优美的性质.一个无向图是弦图当且仅当它有一个完美消除序列,完美消除序列就是 ...
- [NOIP模拟26]题解
今天的考试题改自闭了……所以滚来写陈年题解. A.*****贪婪***** RT,出题人告诉我们这题要贪心. 最优的策略一定是拖到必须断的时候再断开(虽然并不知道为什么). 如果一段序列满足题目中的性 ...