摘要:一般差異簡單來說,是一個用于線程同步的實例方法。暫停當前線程,不釋放任何鎖。用來線程間通信,使擁有該對象鎖的線程等待直到指定時間或。執行對該對象加的同步代碼塊。
一般差異在JAVA的學習中,不少人會把sleep和wait搞混,認為都是做線程的等待,下面主要介紹下這倆者是什么,及了解它們之間的差異和相似之處。
簡單來說,wait()是一個用于線程同步的實例方法。因為定義在java.lang.Object上,所以它可以在任何對象中調用, 但前提條件是在同步代碼塊中調用,同時釋放對象上的鎖,以便另一個線程可以跳入并獲取鎖。而Thread.sleep()是可以從任何上下文調用的靜態方法。Thread.sleep()暫停當前??線程,不釋放任何鎖。
主要區別
sleep()線程控制自身流程。wait()用來線程間通信,使擁有該對象鎖的線程等待直到指定時間或notify()。
wait()會釋放鎖和監視器,sleep()不釋放任何鎖或監視器等。wait()用于線程間通信,而sleep()用于在執行時引入暫停
適用區域,wait只能放在同步語句塊中才有意義。
注意事項wait可以代替sleep嗎?
不可以,如果直接調用wait會拋出java.lang.IllegalMonitorStateException異常,原因是還沒有得到對象鎖,所以無法釋放鎖。
如何獲取鎖?
執行對象的synchronized實例方法。
執行對象對應類的synchronized靜態方法。
執行對該對象加synchronized的同步代碼塊。
演示Thread.sleep
static void method1() { synchronized (LOCK) { try { System.out.println("[" + Thread.currentThread().getName() + "] begin sleep ..."); Thread.sleep(5_000); System.out.println("[" + Thread.currentThread().getName() + "] end sleep ..."); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Stream.of("T1", "T2").forEach(name -> new Thread(DifferenceOfWaitAndSleep::method1, name).start()); }
運行此示例一共將一共耗時10S,因T1線程獲得鎖后會暫停執行,這時候LOCK依舊在T1線程中,然后才會被T2線程獲取
[T1] begin sleep ... [T1] end sleep ... [T2] begin sleep ... [T2] end sleep ...
Object.wait
static void method2() { synchronized (LOCK) { try { System.out.println("[" + Thread.currentThread().getName() + "] begin wait ..."); LOCK.wait(); System.out.println("[" + Thread.currentThread().getName() + "] end wait ..."); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Stream.of("T1", "T2").forEach(name -> new Thread(DifferenceOfWaitAndSleep::method2, name).start()); }
運行此示例會立即輸出T1/T2 begin wait ... 但永遠不會輸出T1/T2 end wait ...,因為沒有線程調用LOCK.notify/notifyAll將它們喚醒
[T1] begin wait ... [T2] begin wait ...結論
調用:
wait(): 對象調用,當前線程必須在持有鎖的對象上進行同步。 sleep(): 線程調用,始終執行的當前線程
同步:
wait(): 同步多個線程同時訪問一個對象時 sleep(): 多個線程同步等待線程休眠
鎖:
wait(): 釋放鎖,其它線程有機會執行 sleep(): 持有鎖,固定時間后釋放或被打斷(interrupt)
喚醒條件:
wait(): 直到調用對象的 notify、notifyAll sleep(): 直到至少時間到期或者調用interrupt()
使用:
sleep(): 用于時間同步 wait(): 用于多線程同步- 說點什么
全文代碼:https://gitee.com/battcn/battcn-concurent/tree/master/Chapter1-1/battcn-thread/src/main/java/com/battcn/chapter8
個人QQ:1837307557
battcn開源群(適合新手):391619659
微信公眾號:battcn(歡迎調戲)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67711.html
摘要:文本將介紹兩種可以優雅的終止線程的方式第一種在多線程模式中有一種叫兩步終止的模式可以優雅的終止線程,這種模式采用了兩個步驟來終止線程,所以叫兩步終止模式。 Java中原來在Thread中提供了stop()方法來終止線程,但這個方法是不安全的,所以一般不建議使用。文本將介紹兩種可以優雅的終止線程的方式... 第一種 在JAVA《Java多線程模式》中有一種叫Two-Phase Term...
摘要:不釋放持有的鎖,釋放鎖。在調用方法前,必須持有鎖,調用喚醒,也要持有鎖。休眠一定時間后,進入就緒狀態。這兩個都能被方法中斷當前狀態。用法方獲取鎖判斷條件,不滿足繼續滿足執行其他業務方獲取鎖改變條件通知為什么是而不是會一直循環,直到條件滿足。 sleep和wait sleep是Thread類的方法,wait是Object的方法。 sleep可以到處使用,wait必須是在同步方法或者代碼...
摘要:和是配套使用的,方法容易導致死鎖。方法不會保證線程的資源正常釋放方法給線程打個停止標記,將線程的中斷狀態設置為,并沒有馬上強制中斷線程,線程是否中斷由線程自己決定。終結狀態,還是返回。方法判斷當前線程是否中斷,清除中斷標志。 resume、suspend、stop resume和suspend是配套使用的,suspend方法容易導致死鎖。 stop方法不會保證線程的資源正常釋放 i...
摘要:并且,線程池在某些情況下還能動態調整工作線程的數量,以平衡資源消耗和工作效率。同時線程池還提供了對池中工作線程進行統一的管理的相關方法。 開發中經常會遇到各種池(如:連接池,線程池),它們的作用就是為了提高性能及減少開銷,在JDK1.5以后的java.util.concurrent包中內置了很多不同使用場景的線程池,為了更好的理解它們,自己手寫一個線程池,加深印象。 概述 1.什么是...
摘要:當時,會進入循環,系統會判斷主線程是否處于活躍狀態,如果處于活躍狀態,主線程就會不停的等待。 由于前段時間比較忙,線程這快學習停滯了,只能利用周日的時間來寫寫博客了,多線程Join方法的作用就是把指定的線程加入到當前線程,讓主線程等待子線程結束之后才能繼續運行,從而完成同步操作 介紹 join() 的作用:讓主線程等待子線程結束之后才能繼續運行,首先先來看下以采集為案例的代碼,統計采...
閱讀 3574·2019-08-30 15:55
閱讀 1373·2019-08-29 16:20
閱讀 3656·2019-08-29 12:42
閱讀 2661·2019-08-26 10:35
閱讀 1010·2019-08-26 10:23
閱讀 3405·2019-08-23 18:32
閱讀 897·2019-08-23 18:32
閱讀 2892·2019-08-23 14:55