程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java信號量模型實際應用手冊

Java信號量模型實際應用手冊

編輯:關於JAVA

Java信號量模型需要我們不斷的進行學習,在學習的時候會有不少的問題阻礙著我們。下面我們就來看看同步鎖模型只是最簡單的同步模型。同一時刻,只有一個線程能夠運行同步代碼。

  有的時候,我們希望處理更加復雜的同步模型,比如生產者/消費者模型、讀寫同步模型等。這種情況下,同步鎖模型就不夠用了。我們需要一個新的模型。這就是我們要講述的Java信號量模型。

  Java信號量模型的工作方式如下:線程在運行的過程中,可以主動停下來,等待某個Java信號量模型的通知;這時候,該線程就進入到該信號量的待召(Waiting)隊列當中;等到通知之後,再繼續運行。

  很多語言裡面,同步鎖都由專門的對象表示,對象名通常叫Monitor。同樣,在很多語言中,Java信號量模型通常也有專門的對象名來表示,比如,Mutex,Semphore。

  Java信號量模型要比同步鎖模型復雜許多。一些系統中,信號量甚至可以跨進程進行同步。另外一些信號量甚至還有計數功能,能夠控制同時運行的線程數。

  我們沒有必要考慮那麼復雜的模型。所有那些復雜的模型,都是最基本的模型衍生出來的。只要掌握了最基本的信號量模型——“等待/通知”模型,復雜模型也就迎刃而解了。

  我們還是以Java語言為例。Java語言裡面的同步鎖和Java信號量模型概念都非常模糊,沒有專門的對象名詞來表示同步鎖和信號量,只有兩個同步鎖相關的關鍵字——volatile和synchronized。

  這種模糊雖然導致概念不清,但同時也避免了Monitor、Mutex、Semphore等名詞帶來的種種誤解。我們不必執著於名詞之爭,可以專注於理解實際的運行原理。

  在Java語言裡面,任何一個Object Reference都可以作為同步鎖。同樣的道理,任何一個Object Reference也可以作為Java信號量模型。

  Object對象的wait()方法就是等待通知,Object對象的notify()方法就是發出通知。

  具體調用方法為

  (1)等待某個Java信號量模型的通知

  public static final Object signal = new Object();

  … f1() {

  synchronized(singal) { // 首先我們要獲取這個信號量。這個信號量同時也是一個同步鎖

  // 只有成功獲取了signal這個信號量兼同步鎖之後,我們才可能進入這段代碼

  signal.wait(); // 這裡要放棄信號量。本線程要進入signal信號量的待召(Waiting)隊列

  // 可憐。辛辛苦苦爭取到手的Java信號量模型,就這麼被放棄了

  // 等到通知之後,從待召(Waiting)隊列轉到就緒(Ready)隊列裡面

  // 轉到了就緒隊列中,離CPU核心近了一步,就有機會繼續執行下面的代碼了。

  // 仍然需要把signal同步鎖競爭到手,才能夠真正繼續執行下面的代碼。命苦啊。

  需要注意的是,上述代碼中的signal.wait()的意思。signal.wait()很容易導致誤解。signal.wait()的意思並不是說,signal開始wait,而是說,運行這段代碼的當前線程開始wait這個signal對象,即進入signal對象的待召(Waiting)隊列。

  (2)發出某個Java信號量模型的通知

  … f2() {

  synchronized(singal) { // 首先,我們同樣要獲取這個信號量。同時也是一個同步鎖。

  // 只有成功獲取了signal這個信號量兼同步鎖之後,我們才可能進入這段代碼

  signal.notify(); // 這裡,我們通知signal的待召隊列中的某個線程。

  // 如果某個線程等到了這個通知,那個線程就會轉到就緒隊列中

  // 但是本線程仍然繼續擁有signal這個同步鎖,本線程仍然繼續執行

  // 嘿嘿,雖然本線程好心通知其他線程,

  // 但是,本線程可沒有那麼高風亮節,放棄到手的同步鎖

  // 本線程繼續執行下面的代碼

  需要注意的是,signal.notify()的意思。signal.notify()並不是通知signal這個對象本身。而是通知正在等待 signal信號量的其他線程。

  以上就是Object的wait()和notify()的基本用法。

  實際上,wait()還可以定義等待時間,當線程在某Java信號量模型的待召隊列中,等到足夠長的時間,就會等無可等,無需再等,自己就從待召隊列轉移到就緒隊列中了。

  另外,還有一個notifyAll()方法,表示通知待召隊列裡面的所有線程。這些細節問題,並不對大局產生影響。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved