02_wait與sleep方法字節(jié)碼分析

wait

public final void wait()

導(dǎo)致當(dāng)前線程等待,直到另一個(gè)線程為此對(duì)象調(diào)用otify()方法或notifyAll()方法。 換句話說,此方法的行為就像它只是執(zhí)行調(diào)用wait(0)一樣。

當(dāng)前線程必須擁有此對(duì)象的鎖。線程釋放此鎖的所有權(quán)并等待,直到另一個(gè)線程通過調(diào)用notify方法或notifyAll方法通知等待此對(duì)象鎖的線程喚醒。然后線程等待,直到它可以重新獲得鎖的所有權(quán)并繼續(xù)執(zhí)行。

與在單參數(shù)版本中一樣,中斷和虛假喚醒是可能的,并且此方法應(yīng)始終在循環(huán)中使用:

synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
         .. // Perform action appropriate to condition
 }
       

此方法只應(yīng)由持有此對(duì)象鎖的擁有者的線程調(diào)用。有關(guān)線程可以成為鎖擁有者的方式的描述,請(qǐng)參閱notify方法。

示例

Object object = new Object();

object.wait();

上述代碼是否可以正常執(zhí)行?
執(zhí)行結(jié)果如下:

Exception in thread "main" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at com.leofight.concurrency1.MyTest1.main(MyTest1.java:8)

參考api方式修改上述代碼

Object object = new Object();
synchronized (object){
    object.wait();
}

上述代碼是否可以執(zhí)行?
執(zhí)行結(jié)果如下:


屏幕快照 2019-06-19 下午10.37.52.png

public final native void wait(long timeout)

導(dǎo)致當(dāng)前線程等待,直到另一個(gè)線程為該對(duì)象調(diào)用notify()方法或notifyAll()方法,或者指定的時(shí)間已經(jīng)過去。

當(dāng)前線程必須擁有此對(duì)象的監(jiān)視器。

該方法導(dǎo)致當(dāng)前線程(稱為T)將自己放入該對(duì)象的等待集中,然后放棄該對(duì)象上的任何和所有同步聲明。線程T在線程調(diào)度時(shí)被禁用,并處于休眠狀態(tài),直到以下四種情況之一發(fā)生:
①其他一些線程調(diào)用此對(duì)象的notify方法,而線程T恰好被任意選擇為要喚醒的線程。
②其他一些線程為該對(duì)象調(diào)用notifyAll方法。
③其他一些線程中斷線程T。
④指定的實(shí)時(shí)時(shí)間或多或少已經(jīng)過了。但是,如果超時(shí)為零,則不考慮實(shí)時(shí),線程只是等待通知。

然后從該對(duì)象的等待集中刪除線程T,并重新啟用線程調(diào)度。然后,它以通常的方式與其他線程競(jìng)爭(zhēng)對(duì)象上的同步權(quán);一旦它獲得了對(duì)對(duì)象的控制,它對(duì)對(duì)象的所有同步聲明都恢復(fù)到以前的狀態(tài)——也就是說,恢復(fù)到調(diào)用wait方法時(shí)的狀態(tài)。然后線程T從wait方法的調(diào)用返回。因此,從wait方法返回時(shí),對(duì)象和線程T的同步狀態(tài)與調(diào)用wait方法時(shí)的同步狀態(tài)完全相同。
線程也可以在不被通知、中斷或超時(shí)的情況下喚醒,這就是所謂的偽喚醒。雖然這種情況在實(shí)踐中很少發(fā)生,但是應(yīng)用程序必須通過測(cè)試應(yīng)該喚醒線程的條件來(lái)防范這種情況,如果條件不滿足,則繼續(xù)等待。換句話說,等待應(yīng)該總是在循環(huán)中發(fā)生,就像這個(gè)

synchronized (obj) {
  while (<condition does not hold>)
     obj.wait(timeout);
     ... // Perform action appropriate to condition
}

有關(guān)此主題的更多信息,請(qǐng)參見Doug Lea的“Java并發(fā)編程(第二版)”中的3.2.3節(jié)。(Addison-Wesley, 2000),或Joshua Bloch的“有效Java編程語(yǔ)言指南”(Addison-Wesley, 2001)中的第50項(xiàng)。

如果當(dāng)前線程在等待之前或等待期間被任何線程中斷,則拋出InterruptedException。在此對(duì)象的鎖狀態(tài)恢復(fù)到如上所述之前,不會(huì)引發(fā)此異常。
注意,wait方法在將當(dāng)前線程放入該對(duì)象的wait集中時(shí),只解鎖該對(duì)象;當(dāng)前線程可能被同步的任何其他對(duì)象在線程等待時(shí)仍然鎖定。
此方法只能由該對(duì)象監(jiān)視器的所有者線程調(diào)用。有關(guān)線程如何成為監(jiān)視器所有者的描述,請(qǐng)參閱notify方法。

sleep

導(dǎo)致當(dāng)前正在執(zhí)行的線程休眠(暫時(shí)停止執(zhí)行)指定的毫秒數(shù),具體取決于系統(tǒng)計(jì)時(shí)器和調(diào)度程序的精度和準(zhǔn)確性。線程不會(huì)失去任何鎖的擁有權(quán)。

小結(jié)

在調(diào)用wait方法時(shí),線程必須要持有被調(diào)用對(duì)象的鎖,當(dāng)調(diào)用wait方法后,線程就會(huì)釋放掉該對(duì)象的鎖(monitor)。

在調(diào)用Thread類的sleep方法時(shí),線程是不會(huì)釋放掉對(duì)象的鎖的。

反編譯示例類

 concurrency1 javap -c MyTest1 
警告: 二進(jìn)制文件MyTest1包含com.leofight.concurrency1.MyTest1
Compiled from "MyTest1.java"
public class com.leofight.concurrency1.MyTest1 {
  public com.leofight.concurrency1.MyTest1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]) throws java.lang.InterruptedException;
    Code:
       0: new           #2                  // class java/lang/Object
       3: dup
       4: invokespecial #1                  // Method java/lang/Object."<init>":()V
       7: astore_1
       8: aload_1
       9: dup
      10: astore_2
      11: monitorenter
      12: aload_1
      13: invokevirtual #3                  // Method java/lang/Object.wait:()V
      16: aload_2
      17: monitorexit
      18: goto          26
      21: astore_3
      22: aload_2
      23: monitorexit
      24: aload_3
      25: athrow
      26: return
    Exception table:
       from    to  target type
          12    18    21   any
          21    24    21   any
}
?  concurrency1 



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容