日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程的状态转换、sleep()、wait()、yeild()、终止线程的方法、线程之间的协作(join()、wait() notify() notifyAll()、await() signal() )

發布時間:2024/10/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程的状态转换、sleep()、wait()、yeild()、终止线程的方法、线程之间的协作(join()、wait() notify() notifyAll()、await() signal() ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.線程的狀態轉換

1.1 新建(New)

創建后尚未啟動

1.2 可運行(Runnable)

可能正在運行,也可能正在等待 CPU 時間片。

包含了操作系統線程狀態中的 Running 和 Ready。

1.3 阻塞(Blocking)

等待獲取一個排它鎖,如果其線程釋放了鎖就會結束此狀態。

1.4 無限期等待(Waiting)

等待其它線程顯式地喚醒,否則不會被分配 CPU 時間片。

進入方法退出方法
沒有設置 Timeout 參數的 Object.wait() 方法Object.notify() /Object.notifyAll()
沒有設置 Timeout 參數的 Thread.join() 方法被調用的線程執行完畢
LockSupport.park() 方法?

1.5?限期等待(Timed Waiting)

無需等待其它線程顯式地喚醒,在一定時間之后會被系統自動喚醒。

調用 Thread.sleep() 方法使線程進入限期等待狀態時,常常用“使一個線程睡眠”進行描述。

調用 Object.wait() 方法使線程進入限期等待或者無限期等待時,常常用“掛起一個線程”進行描述。

睡眠和掛起是用來描述行為,而阻塞和等待用來描述狀態。

阻塞和等待的區別在于,阻塞是被動的,它是在等待獲取一個排它鎖。而等待是主動的,通過調用 Thread.sleep() 和 Object.wait() 等方法進入。

進入方法退出方法
Thread.sleep() 方法時間結束
設置了 Timeout 參數的 Object.wait()方法時間結束 / Object.notify() /Object.notifyAll()
設置了 Timeout 參數的 Thread.join()方法時間結束 / 被調用的線程執行完畢
LockSupport.parkNanos() 方法-
LockSupport.parkUntil() 方法-

1.6 死亡(Terminated)

可以是線程結束任務之后自己結束,或者產生了異常而結束。

2. sleep()、wait()、yeild()

2.1 簡介

2.1.1 sleep()

sleep()方法是Thread類的靜態方法。

調用此方法是線程用來控制自身的執行流程,會休眠當前正在執行的線程,可能是在執行過程中需要有一段時間不執行任何操作。

但是如果一個線程調用了sleep對象,則會進入阻塞狀態,CPU的擁有權則會被撤去,直到sleep時間到才會進入到就緒狀態,等待下次獲得CPU執行權限再去執行。

public void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();} }

2.1.2 wait()

wait()方法則是Object類的方法。

用于進程間通信

調用wait()方法則會讓當前擁有該對象鎖的線程等待,直到其他線程調用notify()或者notifyAll()方法。

不過開發人員也可以設定一個時間,讓其自動醒來。

調用某個對象的wait()方法的線程就會釋放該對象的鎖,從而使線程所在對象中的其他synchronized方法可以被別的線程使用;

//設置超時: wait(long timeout); wait(long timeout,int nanos); //timeout 單位是ms,naos單位為ns。

2.1.3 yield()

yield()方法是Thread類的靜態方法。

對靜態方法它的調用聲明了當前線程已經完成了生命周期中最重要的部分,可以切換給其它線程來執行。

該方法只是對線程調度器的一個建議,而且也只是建議具有相同優先級的其它線程可以運行。

public void run() {Thread.yield(); }

2.2 對比

2.2.1 sleep()和wait()

?sleep()wait()所屬的類是否釋放鎖蘇醒方式使用的區域是否拋出異常
ThreadObject
不會
參數設置其它線程調用notify()或notifyAll()
任何位置必須放在synchronized同步的obj的臨界區中使用

可能會拋出 InterruptedException

因為異常不能跨線程傳播回 main() 中,因此必須在本地進行處理。

線程中拋出的其它異常也同樣需要在本地進行處理。

wait()、notify()和notifyAll()無需捕獲異常。

2.2.2 sleep()和yield()

① sleep()方法給其他線程運行機會時不考慮線程的優先級,因此會給低優先級的線程以運行的機會;yield()方法只會給相同優先級或更高優先級的線程以運行的機會;

?② 線程執行sleep()方法后轉入阻塞(blocked)狀態,而執行yield()方法后轉入就緒(ready)狀態;?

③ sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常;

④ sleep()方法比yield()方法(跟操作系統CPU調度相關)具有更好的可移植性

表格對比:

?

?sleep()yeild()優先級執行后進入的狀態異常可移植性
不考慮同等或更高優先級的
阻塞blocked就緒ready
InterruptedException未聲明任何異常
更好?

2.3 sleep(1000)方法執行后,該線程在多長時間可獲得對CPU的控制?

sleep()方法指定的是一個線程不會運行的最短時間,當睡眠結束后,線程返回到的是可運行狀態,而不是運行狀態,還需要等待CPU調度執行。

2.4 wait, notify 和 notifyAll這些方法不在thread類里面,在Object類中的原因

簡單的說,由于wait,notify和notifyAll都是鎖級別的操作,把它們定義在Object類中因為鎖屬于對象

一個很明顯的原因是Java提供的鎖是對象級的而不是線程級的,每個對象都有鎖,通過線程獲得。如果線程需要等待某些鎖那么調用對象中的wait()方法就有意義了。如果wait()方法定義在Thread類中,線程正在等待的是哪個鎖就不明顯了。

這三種方法被調用的地方必須都是synchronized修飾的方法或代碼塊中

- wait():在線程的代碼流程中如果某個synchronized方法或者代碼塊執行了某個對象的wait()方法則該對象處于wait狀態,釋放持有的對象鎖,直到該對象調用notify或者notifyAll方法才能被喚醒。正在被執行的線程就會釋放該對象的鎖,進入到阻塞狀態

- notify():喚醒一個處于等待狀態的線程,當然在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且與優先級無關;?喚醒的線程可以獲得對象鎖,然后進入到就緒狀態,等待系統調度然后去執行。

- notityAll():喚醒所有處于等待狀態的線程,該方法并不是將對象的鎖給所有線程。所有的線程被喚醒后,接著進行競爭,獲取對象鎖的線程進入到就緒態,等待系統調度去執行,執行結束后就會釋放對象鎖,之前競爭失敗處于被喚醒階段的線程就會繼續重復剛才的動作,直到所有被喚醒的線程都執行結束。

注意:在執行notify()方法之后,當前線程不會馬上釋放該對象鎖,呈wait狀態的線程也不能馬上獲取該對象鎖,要等到執行notify()方法的線程將程序執行完,也就是退出synchronized代碼塊之后,當前線程才會釋放鎖,呈wait狀態所在的線程才可以獲取該對象鎖。

3. 終止線程的方法

3.1 stop()

當調用Thread.stop()來終止線程時,它會釋放已經鎖定的所有監視資源。

如果當前任何一個受這些監視資源保護的對象處于一個不一致的狀態,其他線程將會“看”到這個不一致的狀態,可能會導致程序運行的不確定性。

3.2 suspend()

容易發生死鎖。

調用suspend()不會釋放鎖,這就導致,如果用一個suspend掛起一個有鎖的線程,那么在鎖恢復之前將不會被釋放。

如果調用了suspend(),線程將試圖取得相同的鎖,程序就會發生死鎖。

Java語言已經不建議用以上兩種方法來終止線程了。

3.3 具體方法

一般采用的方法是,讓線程自行進入Dead狀態。

  • 一個線程進入Dead狀態,即執行完run()方法。

3.3.1 設置flag

通過設置一個flag標志來控制循環是否執行,通過這個方式來讓線程離開run()從而終止線程。

public class MyThread implements Runnable{private volatile boolean flag;public void stop(){falg=false;}public void run(){if(flag){//do something;}} }

3.3.2 用interrupt()方法

上面的方法不適用于線程處于非運行狀態的情況(即,當調用sleep()或wait()或被I/O阻塞),此時可以使用interrupt()打破阻塞的情況。

當interrupt()被調用時,會拋出InterruptedException異常,可通過在run()中捕獲這個異常來讓線程安全退出。

public class MyThread{public static void main(String[] args){Thread thread=new Thread(new Runnable(){public viod run(){System.out.println("Thread go to sleep");try{Thread.sleep(5000);System.out.println("thread finish");}catch(InterruptedException e){System.out.println("thread is interrupted");}}});thread.start();thread.interrupt(); }}

如果程序因為I/O停滯,進入非運行狀態,基本上要等到I/O完成才能離開這個狀態,在這種情況下,無法使用interrupt()方法來使程序離開run()方法。

讓程序離開run()就是使用cloae()方法來關閉流。在這種情況下會已發IOException異常,run()可以通過捕獲這個異常來安全地結束線程。

3.4 return

使用return方法停止線程。

4. 線程之間的協作

當多個線程可以一起工作去解決某個問題時,如果某些部分必須在其它部分之前完成,那么就需要對線程進行協調。

4.1 join()

在線程中調用另一個線程的 join() 方法,會將當前線程掛起,而不是忙等待,直到目標線程結束

對于以下代碼,雖然 b 線程先啟動,但是因為在 b 線程中調用了 a 線程的 join() 方法,b 線程會等待 a 線程結束才繼續執行,因此最后能夠保證 a 線程的輸出先于 b線程的輸出。

public class JoinExample {private class A extends Thread {@Overridepublic void run() {System.out.println("A");}} private class B extends Thread {private A a;B(A a) {this.a = a;} @Overridepublic void run() {try {a.join();} catch (InterruptedException e) {e.printStackTrace();} System.out.println("B");}} public void test() {A a = new A();B b = new B(a);b.start();a.start();} }public static void main(String[] args) {JoinExample example = new JoinExample();example.test(); }

運行結果:

4.2?wait() notify() notifyAll()

調用 wait() 使得線程等待某個條件滿足,線程在等待時會被掛起,當其他線程的運行使得這個條件滿足時,其它線程會調用 notify() 或者 notifyAll() 來喚醒掛起的線程。

它們都屬于 Object 的一部分,而不屬于 Thread。只能用在同步方法或者同步控制塊中使用,否則會在運行時拋出
IllegalMonitorStateExeception

使用 wait() 掛起期間,線程會釋放鎖

  • 這是因為,如果沒有釋放鎖,那么其它線程就無法進入對象的同步方法或者同步控制塊中,
  • 那么就無法執行 notify() 或者notifyAll() 來喚醒掛起的線程,造成死鎖。
public class WaitNotifyExample {public synchronized void before() {System.out.println("before");notifyAll();} public synchronized void after() {try {wait();} catch (InterruptedException e) {e.printStackTrace();} System.out.println("after");} }public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();WaitNotifyExample example = new WaitNotifyExample();executorService.execute(() -> example.after());executorService.execute(() -> example.before()); }

運行結果:

4.3?await() signal() signalAll()

java.util.concurrent 類庫中提供了 Condition 類來實現線程之間的協調,可以在Condition上調用 await() 方法使線程等待,其它線程調用 signal() 或 signalAll() 方法喚醒等待的線程。

相比于 wait() 這種等待方式,await() 可以指定等待的條件,因此更加靈活

使用 Lock 來獲取一個 Condition 對象。

public class AwaitSignalExample {private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public void before() {lock.lock();try {System.out.println("before"); condition.signalAll();} finally {lock.unlock();}} public void after() {lock.lock();try {condition.await();System.out.println("after");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}} }public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();AwaitSignalExample example = new AwaitSignalExample();executorService.execute(() -> example.after());executorService.execute(() -> example.before()); }

運行結果:

?

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的线程的状态转换、sleep()、wait()、yeild()、终止线程的方法、线程之间的协作(join()、wait() notify() notifyAll()、await() signal() )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 一区=区三区乱码 | 一区二区三区在线观看免费视频 | 国产日产精品一区二区三区 | 亚洲va天堂va欧美ⅴa在线 | 欧美一二三区在线观看 | caoprom97 | 色多多在线视频 | 香蕉av在线| www.jizzjizz| 久久电影一区二区 | 亚洲爱爱片 | 人人看人人插 | 国产八区 | 亚洲免费观看高清完整 | 日韩黄色网页 | 99精品在线视频观看 | 日日狠狠久久偷偷四色综合免费 | 伊人色在线视频 | 99精品福利视频 | 免费观看的av网站 | 超碰在线人人草 | 雪花飘电影在线观看免费高清 | 少妇av片| 中文久久久久 | 亚洲春色在线 | sesese99| 亚洲第一色图 | 超碰老司机 | 99热精品国产 | 久久情趣视频 | 国产精品少妇 | 古装做爰无遮挡三级 | 草草影院最新 | 台湾色综合 | 日韩精品免费播放 | 欧美一级xxx | 黑人操欧美人 | 欧美天堂网站 | 亚洲国产精品综合久久久 | 青青视频免费观看 | 经典杯子蛋糕日剧在线观看免费 | 亚洲а∨天堂久久精品2021 | 国产精品一区二区久久毛片 | 青青草免费看 | 狠狠做| re久久| 人妻巨大乳hd免费看 | 国产色91 | 日本泡妞视频 | www国产www| 狠狠干影视 | 99久久精品久久久久久清纯 | 亚洲欧美在线观看视频 | 精品一区二区三区无码视频 | 兔费看少妇性l交大片免费 日韩高清不卡 | 91丨国产丨捆绑调教 | 新疆毛片| 日韩精品资源 | 国产精品乱轮 | 以女性视角写的高h爽文 | 亚洲最大色网站 | 国产拍拍拍拍拍拍拍拍拍拍拍拍拍 | 国产日本在线播放 | 欧美天堂在线观看 | 奇米影视在线观看 | 国产福利视频在线 | 国产男女猛烈无遮挡免费视频 | 国产成人在线免费视频 | 巨乳在线播放 | 中文字幕免费高清网站 | 黄色片小视频 | 一级免费看 | 午夜影院免费 | 国产精品一级片在线观看 | 色不卡| 精品国产乱码久久久久 | 久久精品久久国产 | 99在线无码精品入口 | 日韩欧美a级片 | 春物催眠 | 久久精品视频8 | 久久久久久影视 | av大片网| 国产精品女人久久久 | 奇米成人影视 | 波多野结衣1区2区3区 | 国产成人亚洲精品 | 午夜精品久久久久久毛片 | 播播成人网 | 殴美一级黄色片 | 亚洲xxxxxx| 天堂中文在线资 | 久久99久久99精品蜜柚传媒 | 久久免费视频播放 | 国产综合视频在线观看 | 女人喂男人奶水做爰视频 | 黄色草逼视频 | 国产1区2区在线观看 | 午夜精品一区二区三区在线视频 |