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