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()来作为锁的解决 ...
随机推荐
- 从零开始做一个Jmeter性能测试
安装Jmeter 1.下载地址http://jmeter.apache.org/download_jmeter.cgi 2.解压下载文件,然后将bin目录添加到系统环境变量PATH里. 3.确保已安装 ...
- SnowFlake --- 分布式id生成算法
转载自:https://segmentfault.com/a/1190000011282426 概述 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进 ...
- 某个应用的CPU使用率居然达到100%,我该怎么做?(三)
某个应用的CPU使用率居然达到100%,我该怎么做?(三) 1. 引 你们好,可爱的小伙伴们^_^! 咱们最常用什么指标来描述系统的CPU性能呢?我想你的答案,可能不是平均负载,也不是CPU上下文切换 ...
- 入门GoldenGate总结
前言 GoldenGate 是oracle官方的一款数据同步产品,类似于msyql的主从复制,配置也稍稍复杂,其中概念一定要搞清楚,不然会被坑的爬不起. 坑 1.数据在线同步(不是指数据初始化),只能 ...
- PCA revisit
都知道PCA可以做降维,那它为什么可以降维,究竟是怎么降维的呢? 1. 为什么我们要降维? 我们的样本数据好好的,为什么要去做降维,第一个要想清楚这个问题. 也许你是要训练一个分类器,觉得当前特征维度 ...
- java实现http协议发送和接收数据
public void sendMessage() throws Exception { System.out.println("调用servlet开始=================&q ...
- mysql数据库帐号权限设置
1.创建帐号 2.给帐号赋权限(xinjinlong帐号只有查看sakila表的权限) 3.更改密码 4.取消授权 revoke all on *.* from sss@localhost ;
- Monkey学习
Monkey是一个工程,生成伟随机事件流(在一段时间内完全不重复的事件流),由种子生成.可以模拟用户,点击,触屏等.最好用来做压力测试.无法做功能测试. adb shell monkey -p -v ...
- [CSP-S模拟测试53]题解
A.u 只涉及到区间修改可以考虑差分,然而如果每一行都差分复杂度还是过高.我们发现差分标记也是连续的(一行横着的一行斜着的),所以可以维护两个 差分的差分,扫两遍统计即可. #include<c ...
- [CSP-S模拟测试ex]题解
爆零了.少特判见祖宗.还好这场不计入总分. 考场上什么都没想.感觉考试状态又回到了两个月前. A.Antipalindrome 手玩样例,不难发现题目中要求的合法串的充要条件是:对于任意$i \in ...