1. 促進進程和線程出現的原因,是要解決以下問題:
2. 進程: 作業系統為各個獨立執行的進程分配各種資源,包括記憶體,檔案控制代碼以及安全性憑證等。進程之間可以通過一些粗粒度的通訊機制來交換資料,包括:通訊端,訊號處理器,共用內 存,訊號量以及檔案等。
3. 線程:線程允許在同一個進程中同時存在多個程式控制流程。線程會共用進程範圍內的資源,例如記憶體控制代碼和檔案控制代碼,但每個線程都有各自的程式計數器,棧以及局部變數等。線程也被稱為 輕量級的進程,在大多數現代作業系統中,都是以線程為基本的調度單位。
4. 線程的優勢
- 可以發揮多處理器的強大能力:多線程程式可以通過提高處理器資源使用率來提升系統吞吐率。
- 建模的簡單性:比如在編寫Servlet中,不需要瞭解有多少請求在同一時刻要被處理,通訊端的輸入輸出資料流是否被阻塞等問題。
- 非同步事件的簡化處理:比如可以利用多線程把複雜的非阻塞I/O,轉變為同步I/O,即每個請求都擁有自己的處理線程。
- 響應更靈敏的使用者介面:在AWT和Swing等工具中,採用一個事件分發線程來替代主事件迴圈。
5.線程帶來的風險
- 安全性問題:比如競態條件。
- 活躍性問題:比如死結,饑餓,活鎖。
- 效能問題:線程調度是個極大開銷的操作;多個線程共用資料時,必須使用同步機制,而這些機制往往會抑制某些編譯器的最佳化。
6.解決多個線程訪問一個可變的狀態變數導致出現錯誤的三種方式
- 不線上程之間共用該狀態變數
- 將狀態變數修改為不可變的變數
- 在訪問狀態變數時使用同步
7.執行緒安全性
當多個線程訪問某個類時,不管運行環境採用何種調度方式或者這些線程將如何交替執行,並且在主調代碼中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那麼就稱這個類是安全執行緒的。 其中正確性的含義是,某個類的行為與其規範完全一致。在良好的規範中通常會定義各種不變性條件來約束對象的狀態,以及定義各種後驗條件來描述對象操作的結果。
8.競態條件
當某個計算的正確性取決於多個線程的交替執行時序時,那麼就會發生競態條件。
“先檢查後執行”是一種常見的競態條件,它的本質是基於一種可能失效的觀察結果來做出判斷或者執行某個計算。下面的代碼LazyInitRace中就包含一個競態條件,它可能會破壞這個類的正確性。
public class LazyInitRace { private ExpensiveObject instance = null; public ExpensiveObject getInstance() { if (instance == null) { instance = new ExpensiveObject(); } return instance; } }
9.內建鎖
java提供了一種內建的鎖機制來支援原子性:同步代碼塊。它包括兩部分:一個作為鎖的對象引用,一個作為由這個鎖保護的代碼塊。每個Java對象都可以用做一個實現同步的鎖,這些鎖被稱為內建鎖或監視鎖。線程在進入同步代碼塊之前會自動獲得鎖,並且在退出同步代碼塊時自動釋放鎖,而無論是通過正常的控制路徑退出,還是通過從代碼塊中拋出異常退出。獲得內建鎖的唯一途徑就是進入由這個鎖保護的同步代碼塊或方法。
- java的內建鎖是互斥鎖:這意味著最多隻有一個線程能持有這種鎖。
- java的內建鎖是可以重入的:即某個線程試圖獲得一個已經由它自己持有的鎖,那麼這個請求就會成功。