解析Java的多執行緒機制(2)(轉)

ba發表於2007-08-15
解析Java的多執行緒機制(2)(轉)[@more@]實現Runnable介面的多執行緒程式設計方法
  
  Java語言中提供的另外一種實現多執行緒應用程式的方法是多執行緒物件實現Runnable介面並且在該類中定義用於啟動執行緒的run方法。這種定義方式的好處在於多執行緒應用物件可以繼承其它物件而不是必須繼承Thread類,從而能夠增加類定義的邏輯性。
  
  實現Runnable介面的多執行緒應用程式框架程式碼如下所示:
  
  //Consumer.java
  import java.util.*;
  class Consumer implements Runnable
  {
   … …
  public Consumer(int nTime, String strConsumer){… …}
  public void run(){… …}
  static public void main(String args[])
  {
  Thread aConsumer = new Thread(new Consumer(1000, "aConsumer"));
  aConsumer.start();
  //其它物件例項的執行執行緒
   //… …
   }
  }
  
  從上述程式碼可以看出:該類實現了Runnable介面並且在該類中定義了run方法。這種多執行緒應用程式的實現方式與繼承Thread類的多執行緒應用程式的重要區別在於啟動多執行緒物件的方法設計方法不同。在上述程式碼中,透過建立Thread物件例項並且將應用物件作為建立Thread類例項的引數。

  執行緒間的同步
  
  Java應用程式的多個執行緒共享同一程式的資料資源,多個使用者執行緒在併發執行過程中可能同時訪問具有敏感性的內容。在Java中定義了執行緒同步的概念,實現對共享資源的一致性維護。下面以筆者最近開發的行動通訊計費系統中執行緒間同步控制方法,說明Java語言中多執行緒同步方式的實現過程。
  
  在沒有多執行緒同步控制策略條件下的客戶賬戶類定義框架程式碼如下所示:
  
  public class RegisterAccount
  {
  float fBalance;
  //客戶繳費方法
  public void deposit(float fFees){ fBalance += fFees; }
  //通話計費方法
  public void withdraw(float fFees){ fBalance -= fFees; }
  … …
  }
  
  
  
  
  讀者也許會認為:上述程式程式碼完全能夠滿足計費系統實際的需要。確實,在單執行緒環境下該程式確實是可靠的。但是,多程式併發執行的情況是怎樣的呢?假設發生這種情況:客戶在客戶服務中心進行繳費的同時正在利用行動通訊裝置僅此通話,客戶通話結束時計費系統啟動計費程式,而同時服務中心的工作人員也提交繳費程式執行。讀者可以看到如果發生這種情況,對客戶賬戶的處理是不嚴肅的。
  
  如何解決這種問題呢?很簡單,在RegisterAccount類方法定義中加上用於標識同步方法的關鍵字synchronized。這樣,在同步方法執行過程中該方法涉及的共享資源(在上述程式碼中為fBalance成員變數)將被加上共享鎖,以確保在方法執行期間只有該方法能夠對共享資源進行訪問,直到該方法的執行緒執行結束開啟共享鎖,其它執行緒才能夠訪問這些共享資源。在共享鎖沒有開啟的時候其它訪問共享資源的執行緒處於阻塞狀態。
  
  進行執行緒同步策略控制後的RegisterAccount類定義如下面程式碼所示:
  
  public class RegisterAccount
  {
  float fBalance;
  public synchronized void deposit(float fFees){ fBalance += fFees; }
  public synchronized void withdraw(float fFees){ fBalance -= fFees; }
  … …
  }
  
  從經過執行緒同步機制定義後的程式碼形式可以看出:在對共享資源進行訪問的方法訪問屬性關鍵字(public)後附加同步定義關鍵字 synchronized,使得同步方法在對共享資源訪問的時候,為這些敏感資源附加共享鎖來控制方法執行期間的資源獨佔性,實現了應用系統資料資源的一致性管理和維護。



免費註冊
使用者登陸
幫助中心





Matrix首頁 Matrix動態 技術專欄 資源下載 精彩推薦 網站留言 使用者中心 Matrix論壇




今天是:2003年7月16日 星期三 您現在位於: 首頁 → 技術專欄 → java核心技術(java基礎技術)


JAVA教程:解析Java的多執行緒機制(5)
2003-6-7 Matrix讓你不斷進步 瀏覽選項: 顏色 預設 灰度 橄欖色 綠色 藍色 褐色 紅色 本文已被瀏覽 31 次



Java執行緒的管理
  
  
  執行緒的狀態控制
  
  在這裡需要明確的是:無論採用繼承Thread類還是實現Runnable介面來實現應用程式的多執行緒能力,都需要在該類中定義用於完成實際功能的run方法,這個run方法稱為執行緒體(Thread Body)。按照執行緒體在計算機系統記憶體中的狀態不同,可以將執行緒分為建立、就緒、執行、睡眠、掛起和死亡等型別。這些執行緒狀態型別下執行緒的特徵為:
  
  建立狀態:當利用new關鍵字建立執行緒物件例項後,它僅僅作為一個物件例項存在,JVM沒有為其分配CPU時間片等執行緒執行資源;
  
  就緒狀態:在處於建立狀態的執行緒中呼叫start方法將執行緒的狀態轉換為就緒狀態。這時,執行緒已經得到除CPU時間之外的其它系統資源,只等JVM的執行緒排程器按照執行緒的優先順序對該執行緒進行排程,從而使該執行緒擁有能夠獲得CPU時間片的機會。
  
  睡眠狀態:線上程執行過程中可以呼叫sleep方法並在方法引數中指定執行緒的睡眠時間將執行緒狀態轉換為睡眠狀態。這時,該執行緒在不釋放佔用資源的情況下停止執行指定的睡眠時間。時間到達後,執行緒重新由JVM執行緒排程器進行排程和管理。
  
  掛起狀態:可以透過呼叫suspend方法將執行緒的狀態轉換為掛起狀態。這時,執行緒將釋放佔用的所有資源,由JVM排程轉入臨時儲存空間,直至應用程式呼叫resume方法恢復執行緒執行。
  
  死亡狀態:當執行緒體執行結束或者呼叫執行緒物件的stop方法後執行緒將終止執行,由JVM收回執行緒佔用的資源。
  
  在Java執行緒類中分別定義了相應的方法,用於在應用程式中對執行緒狀態進行控制和管理。
  
  執行緒的排程
  
  執行緒呼叫的意義在於JVM應對執行的多個執行緒進行系統級的協調,以避免多個執行緒爭用有限資源而導致應用系統當機或者崩潰。
  
  為了執行緒對於作業系統和使用者的重要性區分開,Java定義了執行緒的優先順序策略。Java將執行緒的優先順序分為10個等級,分別用1-10之間的數字表示。數字越大表明執行緒的級別越高。相應地,在Thread類中定義了表示執行緒最低、最高和普通優先順序的成員變數MIN_PRIORITY、 MAX_PRIORITY和NORMAL_PRIORITY,代表的優先順序等級分別為1、10和5。當一個執行緒物件被建立時,其預設的執行緒優先順序是5。
  
  為了控制執行緒的執行策略,Java定義了執行緒排程器來監控系統中處於就緒狀態的所有執行緒。執行緒排程器按照執行緒的優先順序決定那個執行緒投入處理器執行。在多個執行緒處於就緒狀態的條件下,具有高優先順序的執行緒會在低優先順序執行緒之前得到執行。執行緒排程器同樣採用"搶佔式"策略來排程執行緒執行,即當前執行緒執行過程中有較高優先順序的執行緒進入就緒狀態,則高優先順序的執行緒立即被排程執行。具有相同優先順序的所有執行緒採用輪轉的方式來共同分配CPU時間片。
  
  在應用程式中設定執行緒優先順序的方法很簡單,在建立執行緒物件之後可以呼叫執行緒物件的setPriority方法改變該執行緒的執行優先順序,同樣可以呼叫getPriority方法獲取當前執行緒的優先順序。
  
  在Java中比較特殊的執行緒是被稱為守護(Daemon)執行緒的低階別執行緒。這個執行緒具有最低的優先順序,用於為系統中的其它物件和執行緒提供服務。將一個使用者執行緒設定為守護執行緒的方式是線上程物件建立之前呼叫執行緒物件的setDaemon方法。典型的守護執行緒例子是JVM中的系統資源自動回收執行緒,它始終在低階別的狀態中執行,用於實時監控和管理系統中的可回收資源。
  
  執行緒分組管理
  
  Java定義了在多執行緒執行系統中的執行緒組(ThreadGroup)物件,用於實現按照特定功能對執行緒進行集中式分組管理。使用者建立的每個執行緒均屬於某執行緒組,這個執行緒組可以線上程建立時指定,也可以不指定執行緒組以使該執行緒處於預設的執行緒組之中。但是,一旦執行緒加入某執行緒組,該執行緒就一直存在於該執行緒組中直至執行緒死亡,不能在中途改變執行緒所屬的執行緒組。
  
  當Java的Application應用程式執行時,JVM建立名稱為main的執行緒組。除非單獨指定,在該應用程式中建立的執行緒均屬於 main執行緒組。在main執行緒組中可以建立其它名稱的執行緒組並將其它執行緒加入到該執行緒組中,依此類推,構成執行緒和執行緒組之間的樹型管理和繼承關係。
  
  與執行緒類似,可以針對執行緒組物件進行執行緒組的排程、狀態管理以及優先順序設定等。在對執行緒組進行管理過程中,加入到某執行緒組中的所有執行緒均被看作統一的物件。

  小結:
  本文針對Java平臺中執行緒的性質和應用程式的多執行緒策略進行了分析和講解。
  
  與其它作業系統環境不同,Java執行環境中的執行緒類似於多使用者、多工作業系統環境下的程式,但在程式和執行緒的執行及建立方式等方面,程式與Java執行緒具有明顯區別。
  
  Unix作業系統環境下,應用程式可以利用fork函式建立子程式,但子程式與該應用程式程式擁有獨立的地址空間、系統資源和程式碼執行單元,並且程式的排程是由作業系統來完成的,使得在應用程式之間進行通訊和執行緒協調相對複雜。而Java應用程式中的多執行緒則是共享同一應用系統資源的多個並行程式碼執行體,執行緒之間的通訊和協調方法相對簡單。
  
  可以說:Java語言對應用程式多執行緒能力的支援增強了Java作為網路程式設計語言的優勢,為實現分散式應用系統中多客戶端的併發訪問以及提高伺服器的響應效率奠定堅實基礎。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-958431/,如需轉載,請註明出處,否則將追究法律責任。

相關文章