详解Java多线程tryLock()方法使用
tryLock(long time, TimeUnit unit) 的作用在给定等待时长内锁没有被另外的线程持有,并且当前线程也没有被中断,则获得该锁,通过该方法可以实现锁对象的限时等待。
package com.wkcto.lock.reentrant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
*tryLock(long time, TimeUnit unit) 的基本使用
*/
public class Test07 {
static class TimeLock implements Runnable{
private static ReentrantLock lock = new ReentrantLock(); //定义锁对象
@Override
public void run() {
try {
if ( lock.tryLock(3, TimeUnit.SECONDS) ){ //获得锁返回true
System.out.println(Thread.currentThread().getName() + "获得锁,执行耗时任务");
// Thread.sleep(4000); //假设Thread-0线程先持有锁,完成任务需要4秒钟,Thread-1线程尝试获得锁,Thread-1线程在3秒内还没有获得锁的话,Thread-1线程会放弃
Thread.sleep(2000); //假设Thread-0线程先持有锁,完成任务需要2秒钟,Thread-1线程尝试获得锁,Thread-1线程会一直尝试,在它约定尝试的3秒内可以获得锁对象
}else { //没有获得锁
System.out.println(Thread.currentThread().getName() + "没有获得锁");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
public static void main(String[] args) {
TimeLock timeLock = new TimeLock();
Thread t1 = new Thread(timeLock);
Thread t2 = new Thread(timeLock);
t1.start();
t2.start();
}
}
tryLock()仅在调用时锁定未被其他线程持有的锁,如果调用方法时,锁对象对其他线程持有,则放弃,调用方法尝试获得没,如果该锁没有被其他线程占用则返回true表示锁定成功; 如果锁被其他线程占用则返回false,不等待。
package com.wkcto.lock.reentrant;
import java.util.concurrent.locks.ReentrantLock;
/**
*tryLock()
* 当锁对象没有被其他线程持有的情况下才会获得该锁定
*/
public class Test08 {
static class Service{
private ReentrantLock lock = new ReentrantLock();
public void serviceMethod(){
try {
if (lock.tryLock()){
System.out.println(Thread.currentThread().getName() + "获得锁定");
Thread.sleep(3000); //模拟执行任务的时长
}else {
System.out.println(Thread.currentThread().getName() + "没有获得锁定");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
Runnable r = new Runnable() {
@Override
public void run() {
service.serviceMethod();
}
};
Thread t1 = new Thread(r);
t1.start();
Thread.sleep(50); //睡眠50毫秒,确保t1线程锁定
Thread t2 = new Thread(r);
t2.start();
}
}
package com.wkcto.lock.reentrant;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用tryLock()可以避免死锁
*/
public class Test09 {
static class IntLock implements Runnable{
private static ReentrantLock lock1 = new ReentrantLock();
private static ReentrantLock lock2 = new ReentrantLock();
private int lockNum; //用于控制锁的顺序
public IntLock(int lockNum) {
this.lockNum = lockNum;
}
@Override
public void run() {
if ( lockNum % 2 == 0 ){ //偶数先锁1,再锁2
while (true){
try {
if (lock1.tryLock()){
System.out.println(Thread.currentThread().getName() + "获得锁1, 还想获得锁2");
Thread.sleep(new Random().nextInt(100));
try {
if (lock2.tryLock()){
System.out.println(Thread.currentThread().getName() + "同时获得锁1与锁2 ----完成任务了");
return; //结束run()方法执行,即当前线程结束
}
} finally {
if (lock2.isHeldByCurrentThread()){
lock2.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock1.isHeldByCurrentThread()){
lock1.unlock();
}
}
}
}else { //奇数就先锁2,再锁1
while (true){
try {
if (lock2.tryLock()){
System.out.println(Thread.currentThread().getName() + "获得锁2, 还想获得锁1");
Thread.sleep(new Random().nextInt(100));
try {
if (lock1.tryLock()){
System.out.println(Thread.currentThread().getName() + "同时获得锁1与锁2 ----完成任务了");
return; //结束run()方法执行,即当前线程结束
}
} finally {
if (lock1.isHeldByCurrentThread()){
lock1.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock2.isHeldByCurrentThread()){
lock2.unlock();
}
}
}
}
}
}
public static void main(String[] args) {
IntLock intLock1 = new IntLock(11);
IntLock intLock2 = new IntLock(22);
Thread t1 = new Thread(intLock1);
Thread t2 = new Thread(intLock2);
t1.start();
t2.start();
//运行后,使用tryLock()尝试获得锁,不会傻傻的等待,通过循环不停的再次尝试,如果等待的时间足够长,线程总是会获得想要的资源
}
}
到此这篇关于详解Java多线程tryLock()方法使用的文章就介绍到这了,更多相关Java tryLock()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
在SpringBoot环境中使用Mockito进行单元测试的示例详解
Mockito是一个流行的Java mocking框架,它允许开发者以简单直观的方式创建和使用模拟对象(mocks),Mockito特别适用于在Spring Boot环境中进行单元测试,所以本文介绍了在SpringBoot环境中使用Mockito进行单元测试的示例,需要的朋友可以参考下2024-11-11
SpringBoot整合Sa-Token实现 API 接口签名安全校验功能
这篇文章主要介绍了SpringBoot整合Sa-Token实现 API 接口签名安全校验功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-07-07
Java如何通过反射获取Constructor、Field、Method对象
反射指的是对象的反向处理操作,根据对象取得对象的来源信息,在反射的世界里面,看重的不再是一个对象,而是对象身后的组成,下面这篇文章主要给大家介绍了关于Java如何通过反射获取Constructor、Field、Method对象的相关资料,需要的朋友可以参考下2022-06-06
Java将集合List转换成String字符串(或String转换成List)详解
今天在写项目的时候遇到一个问题,就是要把得到的一个集合转换成字符串,下面这篇文章主要给大家介绍了关于Java将集合List转换成String字符串(或String转换成List)的相关资料,需要的朋友可以参考下2023-06-06


最新评论