Java中Object.wait()和LockSupport.park()的用法
Object.wait() 和 LockSupport.park() 都是用來使當前線程等待的方法,但它們在使用場景和機制上有所不同:
Object.wait()
用途:
wait()方法屬于對象監(jiān)視器(Monitor)的一部分,通常與synchronized塊或方法一起使用。當線程調(diào)用某個對象的wait()方法時,它會釋放該對象的鎖,并使自己進入等待狀態(tài),直到其他線程調(diào)用該對象的notify()或notifyAll()方法喚醒它,此時線程會重新嘗試獲取鎖并繼續(xù)執(zhí)行。位置限制:只能在同步代碼塊或同步方法中調(diào)用,因為需要先獲取到對象的監(jiān)視器鎖。
喚醒條件:可以被
notify()喚醒,意味著有一個或多個等待線程會被喚醒,但具體哪個線程被喚醒是不確定的;也可以被notifyAll()喚醒,這時所有等待該對象監(jiān)視器的線程都會進入鎖的競爭狀態(tài)。
LockSupport.park()
用途:
park()方法屬于java.util.concurrent.locks.LockSupport類,它提供了一種低級別的線程阻塞原語。它不需要與特定的鎖關(guān)聯(lián),可以在任何地方調(diào)用,使得線程阻塞。它通常與unpark()方法配對使用,后者可以喚醒一個調(diào)用了park()的線程。位置限制:沒有位置限制,可以在任何地方調(diào)用,不需要先獲取鎖。
喚醒條件:調(diào)用
LockSupport.unpark(Thread thread)方法可以直接喚醒目標線程,更加靈活和精確。它可以喚醒一個特定的線程,而無需競爭或不確定性。線程許可:
park()和unpark()是基于每個線程的許可(permit)機制。初始時,每個線程沒有許可,調(diào)用unpark()會給指定線程添加一個許可,即使之前已經(jīng)調(diào)用過unpark()給該線程添加了許可,再調(diào)用也不會造成影響(許可不會累積)。調(diào)用park()時,如果沒有許可,線程會阻塞,如果有許可,則消耗許可并繼續(xù)執(zhí)行。
總結(jié)來說,Object.wait() 更適合與同步代碼塊或方法一起使用,與對象的監(jiān)視器鎖緊密相關(guān),適用于傳統(tǒng)的線程協(xié)作場景;而 LockSupport.park() 提供了一種更底層、更靈活的線程阻塞和喚醒機制,適用于更復雜的并發(fā)控制邏輯。
下面是分別使用 Object.wait() 和 LockSupport.park() 的簡單示例:
使用 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(); // 阻塞當前線程
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() + " 準備喚醒線程");
LockSupport.unpark(waitingThread); // 喚醒指定線程
}
}, "UnparkerThread");
waitingThread.start();
unparkerThread.start();
}
}在這兩個例子中,第一個展示了如何使用 Object.wait() 和 notify() 來實現(xiàn)線程間的等待與通知,第二個例子展示了如何使用 LockSupport.park() 和 unpark() 實現(xiàn)類似的線程控制功能,但更為靈活和獨立于特定鎖。
到此這篇關(guān)于Java中Object.wait()和LockSupport.park()的用法的文章就介紹到這了,更多相關(guān)Java Object.wait() LockSupport.park()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用mybatisPlus的queryWrapper做左聯(lián)接,內(nèi)聯(lián)接方式
本文介紹了如何使用Mybatis-Plus的QueryWrapper進行SQL查詢,包括左連接、內(nèi)連接等操作,通過示例代碼展示了如何構(gòu)建復雜的SQL查詢,并將結(jié)果存儲在List對象中返回,希望給讀者提供參考2025-03-03
Java8使用Supplier啟動ScheduledThread代碼實例
這篇文章主要介紹了Java8使用Supplier啟動ScheduledThread詳解,項目開啟立即啟動定時任務是很多項目都會遇到的一個需求,如何利用Java提供的函數(shù)優(yōu)雅的寫出來十分考驗一個人的功底,需要的朋友可以參考下2024-01-01
Springboot升級至2.4.0中出現(xiàn)的跨域問題分析及修改方案
這篇文章主要介紹了Springboot升級至2.4.0中出現(xiàn)的跨域問題分析及修改方案,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
Java項目開發(fā)命名規(guī)范(動力節(jié)點Java學院整理)
定義這個規(guī)范的目的是讓項目中所有的文檔都看起來像一個人寫的,增加可讀性,減少項目組中因為換人而帶來的損失。下面給大家分享java開發(fā)命名規(guī)范,一起看看吧2017-03-03
基于Springboot的漫畫網(wǎng)站平臺設(shè)計與實現(xiàn)
本文將基于Springboot實現(xiàn)開發(fā)一個漫畫主題的網(wǎng)站,實現(xiàn)一個比漂亮的動漫連載的網(wǎng)站系統(tǒng),界面設(shè)計優(yōu)雅大方,比較適合做畢業(yè)設(shè)計和課程設(shè)計使用,需要的可以參考一下2022-08-08

