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