1. 程式人生 > >Java並發編程入門(二)

Java並發編程入門(二)

編程入門 同時 結果 簡化 java並發編程 java並發 ava 成功 nbsp

1.競態條件 1.1 定義 當某個計算的正確性取決於多個線程的交替執行時序時,就會發生競態條件。換句話說,正確的結果要取決於運氣。 最常見的競態條件類型:先檢查後執行(Check-Then-Act)操作,即通過一個可能失效的觀測結果來決定下一步的動作。 1.2 特征 與大多數並發錯誤一樣,競態條件並不總是會產生錯誤,還需要某種不恰當的執行時序。 1.3 復合操作 為了確保線程安全性,“先檢查後執行”(例如延遲初始化)和“讀取-修改-寫入”等操作統稱為復合操作:包含了一組必須以原子方式執行的操作以確保線程安全性。 2 加鎖機制 2.1 在線程安全性定義中要求,多個線程之間的操作無論采用合種執行時序或交替方式,都要保證不變性條件不被破壞。當在不變性條件中涉及多個變量時,各個變量之間並不是彼此獨立的,而是某個變量的值會對其他變量的值產生約束。因此,當更新某一個變量時,需要在同一個原子操作中對其他變量同時進行更新。 2.2 內置鎖
Java提供了一種內置的鎖機制來支持原子性:同步代碼塊(Synchronized Block)。同步代碼塊包括兩部分:一個作為鎖的對象引用,一個作為由這個鎖保護的代碼塊。 每個Java對象都可以用作一個實現同步的鎖,這些鎖被稱為內置鎖(Intrinsic Lock)或監視器鎖(Monitor Lock)。線程在進入同步代碼塊之前會自動獲得鎖,並且在退出同步代碼塊時自動釋放鎖,而無論是通過正常的控制路徑退出,還是通過從代碼塊中拋出異常退出。獲得內置鎖的唯一途徑就是進入由這個鎖保護的同步代碼塊或方法。 Java的內置鎖相當於一種互斥體(或互斥鎖),這意味著最多只有一個線程能持有這種鎖。 當線程A嘗試獲取一個由線程B持有的鎖時,線程A必須等待或阻塞,直到線程B釋放這個鎖。如果B永遠不釋放鎖,那麽A也將永遠地等待下去。
2.3 鎖的重入 如果某個線程試圖獲得一個已經由它自己持有的鎖,那麽請求就會成功。 重入進一步提升了加鎖行為的封裝性,因此簡化了面向對象並發代碼的開發。 2.4 用鎖來保護狀態 由於鎖能使其保護的代碼路徑以串行形式來訪問,因此可以通過鎖來構造一些協議以實現對共享狀態的獨占訪問。只要始終遵循這些協議,就能確保狀態的一致性。 2.5 不良並發(Poor Concurrency)應用程序:可同時調用的數量,不僅受到可用處理資源的限制,還受到應用程序本身結構的限制:任意一個請求均需要等待前一個請求執行完成。 確保並發的同時維護線程安全性:縮小同步代碼塊的範圍,並盡量避免將IO等耗時操作加在同步代碼塊中。

Java並發編程入門(二)