Java中Object.wait()和LockSupport.park()的用法
Object.wait() 和 LockSupport.park() 都是用來使當(dāng)前線程等待的方法,但它們?cè)谑褂脠?chǎng)景和機(jī)制上有所不同:
Object.wait()
用途:
wait()方法屬于對(duì)象監(jiān)視器(Monitor)的一部分,通常與synchronized塊或方法一起使用。當(dāng)線程調(diào)用某個(gè)對(duì)象的wait()方法時(shí),它會(huì)釋放該對(duì)象的鎖,并使自己進(jìn)入等待狀態(tài),直到其他線程調(diào)用該對(duì)象的notify()或notifyAll()方法喚醒它,此時(shí)線程會(huì)重新嘗試獲取鎖并繼續(xù)執(zhí)行。位置限制:只能在同步代碼塊或同步方法中調(diào)用,因?yàn)樾枰全@取到對(duì)象的監(jiān)視器鎖。
喚醒條件:可以被
notify()喚醒,意味著有一個(gè)或多個(gè)等待線程會(huì)被喚醒,但具體哪個(gè)線程被喚醒是不確定的;也可以被notifyAll()喚醒,這時(shí)所有等待該對(duì)象監(jiān)視器的線程都會(huì)進(jìn)入鎖的競(jìng)爭(zhēng)狀態(tài)。
LockSupport.park()
用途:
park()方法屬于java.util.concurrent.locks.LockSupport類,它提供了一種低級(jí)別的線程阻塞原語。它不需要與特定的鎖關(guān)聯(lián),可以在任何地方調(diào)用,使得線程阻塞。它通常與unpark()方法配對(duì)使用,后者可以喚醒一個(gè)調(diào)用了park()的線程。位置限制:沒有位置限制,可以在任何地方調(diào)用,不需要先獲取鎖。
喚醒條件:調(diào)用
LockSupport.unpark(Thread thread)方法可以直接喚醒目標(biāo)線程,更加靈活和精確。它可以喚醒一個(gè)特定的線程,而無需競(jìng)爭(zhēng)或不確定性。線程許可:
park()和unpark()是基于每個(gè)線程的許可(permit)機(jī)制。初始時(shí),每個(gè)線程沒有許可,調(diào)用unpark()會(huì)給指定線程添加一個(gè)許可,即使之前已經(jīng)調(diào)用過unpark()給該線程添加了許可,再調(diào)用也不會(huì)造成影響(許可不會(huì)累積)。調(diào)用park()時(shí),如果沒有許可,線程會(huì)阻塞,如果有許可,則消耗許可并繼續(xù)執(zhí)行。
總結(jié)來說,Object.wait() 更適合與同步代碼塊或方法一起使用,與對(duì)象的監(jiān)視器鎖緊密相關(guān),適用于傳統(tǒng)的線程協(xié)作場(chǎng)景;而 LockSupport.park() 提供了一種更底層、更靈活的線程阻塞和喚醒機(jī)制,適用于更復(fù)雜的并發(fā)控制邏輯。
下面是分別使用 Object.wait() 和 LockSupport.park() 的簡(jiǎn)單示例:
使用 Object.wait() 的例子
public class WaitNotifyExample {
public static void main(String[] args) {
final Object monitor = new Object();
Thread waitingThread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (monitor) {
System.out.println(Thread.currentThread().getName() + " 開始等待");
try {
monitor.wait(); // 等待被喚醒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 被喚醒");
}
}
}, "WaitingThread");
Thread notifierThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000); // 模擬一些工作
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (monitor) {
monitor.notify(); // 喚醒等待的線程
System.out.println(Thread.currentThread().getName() + " 發(fā)出了喚醒通知");
}
}
}, "NotifierThread");
waitingThread.start();
notifierThread.start();
}
}使用 LockSupport.park() 的例子
import java.util.concurrent.locks.LockSupport;
public class ParkUnparkExample {
public static void main(String[] args) {
Thread waitingThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 開始等待");
LockSupport.park(); // 阻塞當(dāng)前線程
System.out.println(Thread.currentThread().getName() + " 被喚醒");
}
}, "WaitingThread");
Thread unparkerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000); // 模擬一些工作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 準(zhǔn)備喚醒線程");
LockSupport.unpark(waitingThread); // 喚醒指定線程
}
}, "UnparkerThread");
waitingThread.start();
unparkerThread.start();
}
}在這兩個(gè)例子中,第一個(gè)展示了如何使用 Object.wait() 和 notify() 來實(shí)現(xiàn)線程間的等待與通知,第二個(gè)例子展示了如何使用 LockSupport.park() 和 unpark() 實(shí)現(xiàn)類似的線程控制功能,但更為靈活和獨(dú)立于特定鎖。
到此這篇關(guān)于Java中Object.wait()和LockSupport.park()的用法的文章就介紹到這了,更多相關(guān)Java Object.wait() LockSupport.park()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis 中Mapper使用package方式配置報(bào)錯(cuò)的解決方案
這篇文章主要介紹了Mybatis 中Mapper使用package方式配置報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
springAOP的三種實(shí)現(xiàn)方式示例代碼
這篇文章主要介紹了springAOP的三種實(shí)現(xiàn)方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
SpringBoot 如何從配置文件讀取值到對(duì)象中
這篇文章主要介紹了SpringBoot 如何從配置文件讀取值到對(duì)象中,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java如何通過反射將map轉(zhuǎn)換為實(shí)體對(duì)象
在Java開發(fā)中,常需要將XML配置數(shù)據(jù)轉(zhuǎn)為Map,并最終映射到實(shí)體對(duì)象上,通過單例模式管理XML轉(zhuǎn)換后的Map,并利用Java反射機(jī)制,通過屬性名稱匹配將Map的值賦給實(shí)體對(duì)象的對(duì)應(yīng)屬性,這種方法忽略了數(shù)據(jù)類型轉(zhuǎn)換,適用于數(shù)據(jù)類型一致的簡(jiǎn)單場(chǎng)景,需要類型轉(zhuǎn)換時(shí)2024-09-09
Java微信公眾平臺(tái)開發(fā)(9) 關(guān)鍵字回復(fù)以及客服接口實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開發(fā)第九步,關(guān)鍵字回復(fù)以及客服接口實(shí)現(xiàn),以及遇到該公眾號(hào)暫時(shí)無法提供服務(wù)的解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
java如何對(duì)接企業(yè)微信的實(shí)現(xiàn)步驟
本文主要介紹了java如何對(duì)接企業(yè)微信的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
MyBatis-Plus 如何單元測(cè)試的實(shí)現(xiàn)
這篇文章主要介紹了MyBatis-Plus 如何單元測(cè)試的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08

