Java多線程基礎(chǔ) 線程的等待與喚醒
題圖:花啡,豆是買咖啡機(jī)送的,花是上周陽(yáng)朔旅游買的桂花,給它起了個(gè)名字,叫 Sunday。
咖啡味淡了一點(diǎn)點(diǎn),多了一份桂花的清香。
本篇我們來(lái)研究一下 wait() notify() notifyAll() 。
DEMO1: wait() 與 notify()
public class Test { static class ThreadOne extends Thread {private Callback mCallback;@Overridepublic void run() { work(); if (mCallback != null) {mCallback.onResult(false); }}// 耗時(shí) 3sprivate 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;@Overridepublic void run() { workOne(); System.out.println(' 根據(jù)結(jié)果繼續(xù)做其他事情 ');}private void workOne() { mThreadOne = new ThreadOne(); mThreadOne.setCallback(new ThreadOne.Callback() {@Overridepublic 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;}@Overridepublic void run() { work(); if (mCallback != null) {mCallback.onResult(false); }}// 耗時(shí) 3sprivate 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 {@Overridepublic 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() {@Overridepublic 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() 一次性全部喚醒。
來(lái)自:http://hackeris.me/2017/05/07/thread_base_1/
相關(guān)文章:
1. php使用正則驗(yàn)證密碼字段的復(fù)雜強(qiáng)度原理詳細(xì)講解 原創(chuàng)2. Jsp+Servlet實(shí)現(xiàn)文件上傳下載 文件列表展示(二)3. asp.net core 認(rèn)證和授權(quán)實(shí)例詳解4. ASP將數(shù)字轉(zhuǎn)中文數(shù)字(大寫(xiě)金額)的函數(shù)5. jscript與vbscript 操作XML元素屬性的代碼6. 基于javaweb+jsp實(shí)現(xiàn)企業(yè)車輛管理系統(tǒng)7. XML在語(yǔ)音合成中的應(yīng)用8. ASP.NET MVC使用Boostrap實(shí)現(xiàn)產(chǎn)品展示、查詢、排序、分頁(yè)9. 基于PHP做個(gè)圖片防盜鏈10. Jsp servlet驗(yàn)證碼工具類分享
