Java多線程基礎(chǔ) 線程的等待與喚醒(wait、notify、notifyAll)
本篇我們來(lái)研究一下 wait() notify() notifyAll() 。
DEMO1: wait() 與 notify()
public class Test {
static class ThreadOne extends Thread {
private Callback mCallback;
@Override
public void run() {
work();
if (mCallback != null) {
mCallback.onResult(false);
}
}
// 耗時(shí) 3s
private void work() {
System.out.println(" 正在查詢數(shù)據(jù)庫(kù) 1");
long startTime = System.currentTimeMillis();
while (true) {
if (System.currentTimeMillis() - startTime < 3000) {
continue;
}
break;
}
}
public void setCallback(Callback callback) {
mCallback = callback;
}
public interface Callback {
void onResult(boolean result);
}
}
static class ThreadTest extends Thread {
private Object mLock = new Object();
private ThreadOne mThreadOne;
@Override
public void run() {
workOne();
System.out.println(" 根據(jù)結(jié)果繼續(xù)做其他事情 ");
}
private void workOne() {
mThreadOne = new ThreadOne();
mThreadOne.setCallback(new ThreadOne.Callback() {
@Override
public void onResult(boolean result) {
System.out.println(" 查詢數(shù)據(jù)庫(kù) 1 結(jié)束,:" + (result ? " 有數(shù)據(jù) " : " 無(wú)數(shù)據(jù) "));
synchronized (mLock) {
mLock.notify();
System.out.println("--ThreadTest 結(jié)束等待 --");
}
}
});
mThreadOne.start();
try {
synchronized (mLock) {
System.out.println("--ThreadTest 進(jìn)入等待 --");
mLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] var0) {
ThreadTest threadTest = new ThreadTest();
threadTest.start();
}
}
DEMO1 輸出:
--ThreadTest 進(jìn)入等待-- 正在查詢數(shù)據(jù)庫(kù) 1 查詢數(shù)據(jù)庫(kù) 1 結(jié)束,: 無(wú)數(shù)據(jù) --ThreadTest 結(jié)束等待-- 根據(jù)結(jié)果繼續(xù)做其他事情
注意:
使用 wait() 和 notify() 必須在獲得同步鎖后才能調(diào)用,若直接調(diào)用會(huì)報(bào) java.lang.IllegalMonitorStateException 錯(cuò)誤,因?yàn)闋顟B(tài)由同步鎖保護(hù)。
wait() 不同于 sleep() 的是 wait() 會(huì)釋放同步鎖。
因?yàn)?wait() 和 notify() 是基于同步鎖實(shí)現(xiàn)的,每個(gè)對(duì)象都有自己的同步鎖,所以 wait() 和 notify() 是 Object 的方法,而不是 Thread。
DEMO2,wait() 與 notifyAll():
public class Test {
private static Object mLock = new Object();
static class MyThread extends Thread {
String mName;
Callback mCallback;
public MyThread(String name){
mName = name;
}
@Override
public void run() {
work();
if (mCallback != null) {
mCallback.onResult(false);
}
}
// 耗時(shí) 3s
private void work() {
System.out.println(mName + " 等待 ");
try {
synchronized (mLock) {
mLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void setCallback(Callback callback) {
mCallback = callback;
}
public interface Callback {
void onResult(boolean result);
}
}
static class ThreadTest extends Thread {
@Override
public void run() {
work("db1");
work("db2");
work("db3");
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mLock) {
System.out.println(" 喚醒全部 ");
mLock.notifyAll();
}
}
private void work(String name) {
final MyThread myThread = new MyThread(name);
myThread.setCallback(new MyThread.Callback() {
@Override
public void onResult(boolean result) {
System.out.println(myThread.mName + " 回來(lái)了 ");
}
});
myThread.start();
}
}
public static void main(String[] var0) {
ThreadTest threadTest = new ThreadTest();
threadTest.start();
}
}
DEMO2 輸出:
db1 等待
db3 等待
db2 等待
喚醒全部
db3 回來(lái)了
db1 回來(lái)了
db2 回來(lái)了
同一個(gè)對(duì)象的 wait() 方法可多次在不同的線程中調(diào)用,可讓不同的線程進(jìn)入等待(阻塞),可以一個(gè)一個(gè) notify(),也可以調(diào)用 notifyAll() 一次性全部喚醒。
相關(guān)文章
java如何實(shí)現(xiàn)socket連接方法封裝
這篇文章主要介紹了java實(shí)現(xiàn)socket連接方法封裝教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java 滑動(dòng)窗口最大值的實(shí)現(xiàn)
這篇文章主要介紹了Java 滑動(dòng)窗口最大值,給定一個(gè)數(shù)組 nums,有一個(gè)大小為 k 的滑動(dòng)窗口從數(shù)組的最左側(cè)移動(dòng)到數(shù)組的最右側(cè)。感興趣的可以了解一下2021-05-05
使用java技術(shù)抓取網(wǎng)站上彩票雙色球信息詳解
這篇文章主要介紹了使用java技術(shù)抓取網(wǎng)站上彩票雙色球信息詳解,web結(jié)果由html+js+css組成,html結(jié)構(gòu)都有一定的規(guī)范,數(shù)據(jù)動(dòng)態(tài)交互可以通過(guò)js實(shí)現(xiàn)。,需要的朋友可以參考下2019-06-06
Java精品項(xiàng)目瑞吉外賣之新增菜品與分頁(yè)查詢篇
這篇文章主要為大家詳細(xì)介紹了java精品項(xiàng)目-瑞吉外賣訂餐系統(tǒng),此項(xiàng)目過(guò)大,分為多章獨(dú)立講解,本篇內(nèi)容為新增菜品和分頁(yè)查詢功能的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
JAVA基礎(chǔ)之基本數(shù)據(jù)類型全面解析
下面小編就為大家?guī)?lái)一篇JAVA基礎(chǔ)之基本數(shù)據(jù)類型全面解析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
SpringBoot整合Mybatis與MybatisPlus方法詳細(xì)講解
這篇文章主要介紹了SpringBoot整合Mybatis與MybatisPlus方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
使用SpringMVC響應(yīng)json格式返回的結(jié)果類型
這篇文章主要介紹了使用SpringMVC響應(yīng)json格式返回的結(jié)果類型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
JavaWeb開發(fā)入門第二篇Tomcat服務(wù)器配置講解
JavaWeb開發(fā)入門第二篇主要介紹了Tomcat服務(wù)器配置的方法教大家如何使用Tomcat服務(wù)器,感興趣的小伙伴們可以參考一下2016-04-04
Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot統(tǒng)一處理全局異常的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
Java Mybatis中的 ${ } 和 #{ }的區(qū)別使用詳解
這篇文章主要介紹了Mybatis中的 ${ } 和 #{ }的區(qū)別使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

