線程中sleep()方法和wait()方法的前生今世


先看再點贊,給自己一點思考的時間,如果對自己有幫助,微信搜索【程序職場】關注這個執着的職場程序員。
我有什么:職場規划指導,技能提升方法,講不完的職場故事,個人成長經驗。

 

 

不知道大家有沒有這種感覺,在公司項目忙碌的時候,有時候感覺又忙又累,甚至加班通宵都有,能忙死人,每天想着輕松點吧,能休息休息做點別的什么。

但是當項目收尾不忙(不忙是指不用加班)的時候,如果一天兩天還好,但是時間超出一周(不是沒事干,是不像之前每天加班才能完成任務,現在每天8個小時不到就完成了任務),總是感覺太閑了,不太充實了,不知道該干什么。這邊找點事,那邊找點事

有時候甚至想着還是忙點吧。


所以趁着最近幾天不是太忙,對自己做了一個復盤,發現我計划的東西還有一半沒有完成(比如:我讀的書 和 寫的教程還只是做到2/1),所以還要加油,更主要的是 公眾號文章的更新以后要保持下去。

好了不發感慨了,開始我們今天的線程篇(這些文章目前已經做了分類,多了就能成系統了)。

 

1,sleep和wait概念

Java中的多線程是一種搶占式的機制。
線程主要有以下幾種狀態:可運行,運行,阻塞,死亡。搶占式機制指有多個線程處於可運行狀態,但是只有一個線程在運行。

當有多個線程訪問共享數據的時候,就需要對線程進行同步。線程中的幾個主要方法的比較:

 

Thread類的方法:sleep(),yield()等

Object的方法:wait()和notify()等

 

每個對象都有一個機鎖來控制同步訪問。Synchronized關鍵字可以和對象的機鎖交互,來實現線程的同步。

由於sleep()方法是Thread類的方法,因此它不能改變對象的機鎖

Wait()方法和notify()方法:當一個線程執行到wait()方法時(線程休眠且釋放機鎖),它就進入到一個和該對象相關的等待池中,同時失去了對象的機鎖。

當它被一個notify()方法喚醒時,等待池中的線程就被放到了鎖池中。該線程從鎖池中獲得機鎖,然后回到wait()前的中斷現場。

共同點: 他們都是在多線程的環境下,都可以在程序的調用處阻塞指定的毫秒數,並返回。

不同點: Thread.sleep(long)可以不在synchronized的塊下調用,而且使用Thread.sleep()不會丟失當前線程對任何對象的同步鎖(monitor);

object.wait(long)必須在synchronized的塊下來使用,調用了之后失去對object的monitor, 這樣做的好處是它不影響其它的線程對object進行操作。

 

2. sleep和wait方法的應用場景

sleep 休眠方法:

Static void sleep(long ms)

該方法會使當前線程進入阻塞狀態指定毫秒,當阻塞指定毫秒后,當前線程會重新進入Runnable狀態,等待划分時間片。

wait方法一般是跟notify方法連用的:

多線程之間需要協調工作。如果條件不滿足則等待。當條件滿足時,等待該條件的線程將被喚醒。在Java中,這個機制實現依賴於wait/notify。

 

3,簡單使用

一,Sleep()

  1. Sleep方法屬於Thread類,調用Sleep時會暫停此線程指定的時間,但它的監控一直在監控着,Sleep不會釋放對象的鎖,到了一定時間它會自動喚醒。

  2. Sleep方法有接收時間參數,Therad.Sleep(1000)  其中參數都是毫秒值。

public class ThreadSleep {

public static void main(String[] args) {// write your code here

int time = 10;
for (int i=1;i<=time;i++) {

try {

Thread.sleep(1000);

System.out.println("線程休眠時間=" + i +"秒");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}


上面的代碼循環中間隔一秒輸出一個信息。

 

線程休眠時間=1秒
線程休眠時間=2秒
線程休眠時間=3秒
線程休眠時間=4秒
線程休眠時間=5秒
線程休眠時間=6秒
線程休眠時間=7秒
線程休眠時間=8秒
線程休眠時間=9秒
線程休眠時間=10秒

Process finished with exit code 0

 

二,Wait()

1.Wait()方法屬於Object類,調用Wait方法時,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有此對象調用notify()方法后本線程才進入對象鎖定池准備,wait方法需要被動喚醒,
2. wait方法不需要時間參數

public class ThreadWait { public static void main(String[] args) { 
/**
* 作者:公眾號:程序職場 * 代碼描述:創建兩個線程一個操作年齡的信息,一個是工作量的信息 */
//輸出年齡信息

Object obj=new Object();

Thread download=new Thread(){


public void run() {

System.out.println("開始輸出年齡");

for (int i = 1; i < 6; i+=1) {

System.out.println("年齡="+i);

}

System.out.println("年齡輸出成功");

synchronized (obj) {

System.out.println("喚起");

obj.notify();//喚起wait的等待

}

System.out.println("開始輸出工作量");


for (int i = 1; i < 6; i+=1) {

System.out.println("工作量="+i+"小時");

}

System.out.println("工作量輸出成功");

}

};
//2.年齡輸出成果的結果
Thread show=new Thread(){

public void run(){

synchronized (obj) {


try {

System.out.println("阻塞");

obj.wait();//阻塞當前

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("年齡完成");

}

}

};

download.start();

show.start();

}
}

1,show線程中阻塞線程(wait)​
2,download線程中 喚醒(notify)

本文 Github ( 碼雲Gitee同步) https://github.com/ProceduralZC/JavaDevGuide/tree/master/code/JavaTheead/ThreadClass  已收錄,歡迎 star。

 

 

 

 

我是【爾東雙月】一枚執着的職場程序員,微信搜索【程序職場】關注我。別忘了三連啊,點贊、收藏、留言,隨意給,我不挑。
知乎號: 程序職場
注:如果文章有任何問題,歡迎毫不留情地指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM