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()来作为锁的解决 ...
随机推荐
- CentOS使用手册(一)
前言:全栈开发当然少不了服务器的配置与维护,本次打算参考网上资料和大地老师的视频写一个CentOS系列的手册,方便日后查阅. 本篇目录: 1.虚拟机上的CentOS基本安装流程 2.远程连接Linux ...
- C中printf函数的用法总结
函数语法 stdio.h文件中的定义: /* Write formatted output to stdout. */ int printf (const char *__restrict __for ...
- postman使用之四:设置读取变量和切换环境
postman提供了environment管理功能,想要在多个环境中测试,比如在测试环境.灰度环境.生产环境等,只需要用同样的接口,切换下环境即可,非常方便.具体步骤: 设置环境变量 1.点击man ...
- Linux下创建动态库与使用
参考文章:dll和so文件区别与构成:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html 动态库路径配置- /etc/ld.so. ...
- AtCoder Beginner Contest 130 F Minimum Bounding Box 三分法求极值(WA)
题意:给n个点的起始坐标以及他们的行走方向,每一单位时间每个点往它的方向移动一单位.问最小能包围所有点的矩形. 解法:看到题目求极值,想了想好像可以用三分法求极值,虽然我也不能证明面积是个单峰函数. ...
- 力扣—Remove Nth Node From End of List(删除链表的倒数第N个节点) python实现
题目描述: 中文: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二 ...
- qt学习(二):启动画面
打开一个软件,都会有启动画面. 现在去体验如何实现启动画面:输入图,装载,延时,下一张主部件图 在main.Cpp中实现启动时桌面图片. #include <QtGui/QApplication ...
- 修改Tomcat的server.xml之后,tomcat 部署项目报错:Removing obsolete files from server... Could not clean server of obsolete files: null java.lang.NullPointerException
介个是你在clean tomcat的时候 文件没有clean清.(临时崩溃 系统宕机或其他原因)导致自己eclipse里的service.xml 在clean时没有copy一致. 解决方案: 1找到你 ...
- 基于Vue2、WebSocket的仿腾讯QQ
概述 本项目基于Vue2进行高仿手机QQ的webapp,UI上使用的是museUI,使用springMVC搭建的后台.聊天方面,使用WebSocket实现浏览器与服务器全双工通信,允许服务器主动发送信 ...
- Gym101158 J 三分 or 模拟退火 Cover the Polygon with Your Disk
目录 Gym101158 J: 求圆与给定凸多边形最大面积交 模拟退火 三分套三分 模拟退火套路 @ Gym101158 J: 求圆与给定凸多边形最大面积交 传送门:点我点我 求 $10 $ 个点组成 ...