先看再點贊,給自己一點思考的時間,如果對自己有幫助,微信搜索【程序職場】關注這個執着的職場程序員。
我有什么:職場規划指導,技能提升方法,講不完的職場故事,個人成長經驗。
不知道大家有沒有這種感覺,在公司項目忙碌的時候,有時候感覺又忙又累,甚至加班通宵都有,能忙死人,每天想着輕松點吧,能休息休息做點別的什么。
但是當項目收尾不忙(不忙是指不用加班)的時候,如果一天兩天還好,但是時間超出一周(不是沒事干,是不像之前每天加班才能完成任務,現在每天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()
-
Sleep方法屬於Thread類,調用Sleep時會暫停此線程指定的時間,但它的監控一直在監控着,Sleep不會釋放對象的鎖,到了一定時間它會自動喚醒。
-
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。
我是【爾東雙月】一枚執着的職場程序員,微信搜索【程序職場】關注我。別忘了三連啊,點贊、收藏、留言,隨意給,我不挑。
知乎號: 程序職場
注:如果文章有任何問題,歡迎毫不留情地指正。