Java高併發程式設計---入門
為什麼需要並行
- 單核CPU效能瓶頸
- 平行計算還出於業務模型的需要並不是為了提高系統性能,而是確實在業務上需要多個執行單元。 – 比如HTTP伺服器,為每一個Socket連線新建一個處理執行緒 – 讓不同執行緒承擔不同的業務工作 (主執行緒 gc執行緒) – 簡化任務排程
平行計算的試用的領域
- 影象處理
- 伺服器端程式設計
幾個重要的概念
同步(synchronous)和非同步(asynchronous) 併發(Concurrency)和並行(Parallelism) 臨界區 阻塞(Blocking)和非阻塞(Non-Blocking) 鎖(Deadlock)、飢餓(Starvation)和活鎖(Livelock) 並行的級別
- 同步(synchronous)和非同步(asynchronous)
同步:提交請求->等待伺服器處理->處理完畢返回 這個期間客戶端瀏覽器不能幹任何事
非同步: 請求通過事件觸發->伺服器處理(這是瀏覽器仍然可以作其他事情)->處理完畢
2、併發(Concurrency)和並行(Parallelism)
3 、臨界區
臨界區用來表示一種公共資源或者說是共享資料,可以被多個執行緒使用。但是每一次,只能有一個執行緒 使用它,一旦臨界區資源被佔用,其他執行緒要想使用這個資源,就必須等待。
4、阻塞(Blocking)和非阻塞(Non-Blocking)
阻塞和非阻塞通常用來形容多執行緒間的相互影響。比如一個執行緒佔用了臨界區資源,那麼其他所有需要這個資源的執行緒就必須在這個臨界區中進行等待。等待會導致執行緒掛起,這種情況就是阻塞。非阻塞的意思與之相反,它強調沒有一個執行緒可以妨礙其他執行緒執行。所有的執行緒都會嘗試不斷前向執行。
阻塞 傳統的 IO 流都是阻塞式的。也就是說,當一個執行緒呼叫 read() 或 write()時,該執行緒被阻塞,直到有一些資料被讀取或寫入,該執行緒在此期間不能執行其他任務。因此,在完成網路通訊進行 IO 操作時,由於執行緒會阻塞,所以伺服器端必須為每個客戶端都提供一個獨立的執行緒進行處理,當伺服器端需要處理大量客戶端時,效能急劇下降
非阻塞 Java NIO 是非阻塞模式的。當執行緒從某通道進行讀寫資料時,若沒有資料可用時,該執行緒可以進行其他任務。執行緒通常將非阻塞 IO 的空閒時間用於在其他通道上執行 IO 操作,所以單獨的執行緒可以管理多個輸入和輸出通道。因此,NIO 可以讓伺服器端使用一個或有限幾個執行緒來同時處理連線到伺服器端的所有客戶端。
5、死鎖(Deadlock)、飢餓(Starvation)和活鎖(Livelock)
多執行緒產生死鎖的四個必要條件:
互斥條件:一個資源每次只能被一個程序使用。 保持和請求條件:一個程序因請求資源而阻塞時,對已獲得資源保持不放。 不可剝奪調教:程序已獲得資源,在未使用完成前,不能被剝奪。 迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。
併發級別
阻塞 當一個執行緒進入臨界區後,其他執行緒必須等待
無飢餓
無障礙 – 無障礙是一種最弱的非阻塞排程 – 自由出入臨界區 – 無競爭時,有限步內完成操作 – 有競爭時,回滾資料
無鎖(Lock-Free)
– 首先是無障礙的 – 保證有一個執行緒可以勝出
無等待(Wait-Free)
– 無鎖的 – 要求所有的執行緒都必須在有限步內完成 – 無飢餓的