關於java的wait、notify、notifyAll方法

wait、notify、notifyAll

遇到的問題

以前開發打印機項目,由於須要使用多線程技術,當時並不怎麼理解,一開始隨意在方法體內使用wait、notify、notifyAll 方法致使出現了一大堆 IllegalMonitorStateException 異常。爲何會出現這個異常這和這三個方法內部的機制有關。java

同步機制

wait 和 notify 是 java 同步機制中重要組成部分。使用時需結合 synchronized 關鍵字。 
同步分爲類級別和對象級別,分別對應着類鎖和對象鎖。其實類也能夠當作是一個 Class 對象。每一個類只有一個類鎖,每一個對象也只有一個對象鎖。要想達到同步狀態,操做時必須獲取對應的對象/類鎖,保證其餘地方不能同時更改對象/類的狀態。多線程

 

關於 wait、notify、notifyAll

  • wait 
    調用wait的時候,線程會釋放其佔有的對象鎖,同時不會主動去申請獲取對象鎖,必須等待被喚醒的時候,才擁有得到對象鎖的權利。
  • notify 
    喚醒在等待該對象同步鎖的線程(只喚醒一個,若是有多個對象在等待,並且具備隨機性)
  • -notifyAll 
    喚醒全部在等待該對象同步鎖的線程,該方法雖然是對每一個wait的線程都調用一次notify,但仍是有順序的,每一個對象都保存這一個等待對象鏈,調用的順序就是這個鏈的順序。

注:線程

  調用了wait、notify、notifyAll 方法必須在同步狀態,即已獲取了對象鎖,因此在使用時候必須搭配 synchronized 關鍵字一塊兒用,不然就會拋出 java.lang.IllegalMonitorStateException ,因此以前遇到的問題就是由於在沒有保證同步的時候調用了這些方法。 
  notifyAll 雖然能喚醒全部線程,但並非全部線程馬上得到執行的機會,由於要得到執行的機會,必須首先得到對象鎖,可是同一時刻只有線程可以得到對象鎖。因此在調用 notifyAll 方法以後,同一時刻只有一個線程得到執行的機會,其餘線程須等待該線程執行完畢釋放對象鎖纔有機會執行 
  這三個方法都屬於Object對象,而不屬於線程級別,它們的使用都與鎖有關對象

相關文章
相關標籤/搜索