詳解Java多線程tryLock()方法使用
tryLock(long time, TimeUnit unit) 的作用在給定等待時(shí)長內(nèi)鎖沒有被另外的線程持有,并且當(dāng)前線程也沒有被中斷,則獲得該鎖,通過該方法可以實(shí)現(xiàn)鎖對象的限時(shí)等待。
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() + "獲得鎖,執(zhí)行耗時(shí)任務(wù)");
// Thread.sleep(4000); //假設(shè)Thread-0線程先持有鎖,完成任務(wù)需要4秒鐘,Thread-1線程嘗試獲得鎖,Thread-1線程在3秒內(nèi)還沒有獲得鎖的話,Thread-1線程會放棄
Thread.sleep(2000); //假設(shè)Thread-0線程先持有鎖,完成任務(wù)需要2秒鐘,Thread-1線程嘗試獲得鎖,Thread-1線程會一直嘗試,在它約定嘗試的3秒內(nèi)可以獲得鎖對象
}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()僅在調(diào)用時(shí)鎖定未被其他線程持有的鎖,如果調(diào)用方法時(shí),鎖對象對其他線程持有,則放棄,調(diào)用方法嘗試獲得沒,如果該鎖沒有被其他線程占用則返回true表示鎖定成功; 如果鎖被其他線程占用則返回false,不等待。
package com.wkcto.lock.reentrant;
import java.util.concurrent.locks.ReentrantLock;
/**
*tryLock()
* 當(dāng)鎖對象沒有被其他線程持有的情況下才會獲得該鎖定
*/
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); //模擬執(zhí)行任務(wù)的時(shí)長
}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 ){ //偶數(shù)先鎖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() + "同時(shí)獲得鎖1與鎖2 ----完成任務(wù)了");
return; //結(jié)束run()方法執(zhí)行,即當(dāng)前線程結(jié)束
}
} finally {
if (lock2.isHeldByCurrentThread()){
lock2.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock1.isHeldByCurrentThread()){
lock1.unlock();
}
}
}
}else { //奇數(shù)就先鎖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() + "同時(shí)獲得鎖1與鎖2 ----完成任務(wù)了");
return; //結(jié)束run()方法執(zhí)行,即當(dāng)前線程結(jié)束
}
} 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();
//運(yùn)行后,使用tryLock()嘗試獲得鎖,不會傻傻的等待,通過循環(huán)不停的再次嘗試,如果等待的時(shí)間足夠長,線程總是會獲得想要的資源
}
}
到此這篇關(guān)于詳解Java多線程tryLock()方法使用的文章就介紹到這了,更多相關(guān)Java tryLock()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java并發(fā)編程之阻塞隊(duì)列(BlockingQueue)詳解
- Java中雙重檢查鎖(double checked locking)的正確實(shí)現(xiàn)
- Java并發(fā)編程之ReentrantLock實(shí)現(xiàn)原理及源碼剖析
- java中synchronized Lock(本地同步)鎖的8種情況
- java并發(fā)編程工具類PriorityBlockingQueue優(yōu)先級隊(duì)列
- Java中提供synchronized后為什么還要提供Lock
- Java并發(fā)編程之StampedLock鎖介紹
- Java中l(wèi)ock和tryLock及l(fā)ockInterruptibly的區(qū)別
相關(guān)文章
Idea?編譯并運(yùn)行?Spark?3.1.1?源碼的方法
這篇文章主要介紹了Idea?編譯并運(yùn)行?Spark?3.1.1源碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
Java遞歸實(shí)現(xiàn)斐波那契數(shù)列
這篇文章主要為大家詳細(xì)介紹了Java遞歸實(shí)現(xiàn)斐波那契數(shù)列,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
Java線程池隊(duì)列PriorityBlockingQueue原理分析
這篇文章主要介紹了Java線程池隊(duì)列PriorityBlockingQueue原理分析,PriorityBlockingQueue隊(duì)列是?JDK1.5?的時(shí)候出來的一個(gè)阻塞隊(duì)列,但是該隊(duì)列入隊(duì)的時(shí)候是不會阻塞的,永遠(yuǎn)會加到隊(duì)尾,需要的朋友可以參考下2023-12-12
spring boot 使用profile來分區(qū)配置的操作
這篇文章主要介紹了spring boot使用profile來分區(qū)配置的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Mybatis事務(wù)如何跟Spring結(jié)合(數(shù)據(jù)庫事務(wù)特性和Spring事務(wù)管理源碼)
MyBatis與Spring的事務(wù)結(jié)合主要是通過Spring的事務(wù)管理和MyBatis的數(shù)據(jù)庫操作來實(shí)現(xiàn)的,在本文中,我們將從數(shù)據(jù)庫事務(wù)特性和Spring事務(wù)管理源碼兩個(gè)角度來分析MyBatis事務(wù)如何與Spring結(jié)合到一起的原理,感興趣的朋友一起看看吧2024-01-01
java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段
這篇文章主要為大家詳細(xì)介紹了java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01

