簡要JUC常識概念總結
技術標籤:春招衝關-Java後端Java從入門到禿頭java併發程式設計多執行緒
JUC常識概念
基礎概念
Created: Aug 6, 2020 8:45 PM
Tags: 臨界區, 原子性、可見性、有序性, 同步非同步, 併發並行, 死鎖、飢餓、活鎖
1.同步與非同步
用來形容一次方法呼叫。
- 同步的方法呼叫一旦開始,呼叫者必須等到方法呼叫返回後才能繼續。
- 非同步呼叫類似訊息傳遞,執行後另一個執行緒進行操作,同時本執行緒立即返回
2.併發與並行
- 並行偏重多個任務交替執行,多個任務直接可能還是序列的
- 併發偏重同時執行
3.臨界區
用來表示一種公共資源。可以被多個執行緒使用。但是每次只能有一個執行緒使用。執行緒需要等待其他執行緒使用完該資源。
4.阻塞與非阻塞
用來形容多執行緒之間的相互影響。
- 阻塞在佔用臨界區資源時,其他執行緒必須掛起等待,該執行緒若不釋放資源,其他所有阻塞在這個臨界區的執行緒都不能工作。
- 非阻塞強調沒有一個執行緒可以妨礙其他執行緒執行。所有執行緒都嘗試不斷前進。
5.死鎖、飢餓、活鎖
死鎖
多個執行緒互相佔用對方需要的資源,同時本身不願意放棄自己的資源,導致死鎖
![執行緒死鎖]](https://img-blog.csdnimg.cn/img_convert/d98885594a3ef0970b7af25a57878e1b.png#pic_center)
飢餓
執行緒資源的分配不是根據先到先得的,獲得資源存在了一定的“運氣”,一個執行緒因為種種原因無法獲得所需要的資源,導致無法執行,稱為飢餓
活鎖
多個執行緒互相謙讓,資源始終在兩個執行緒之間跳動,卻沒有被使用。
原子性
指一個操作不可中斷。
對於32位的系統,long型的資料讀寫不是原子性的(long有64位)。
在32位的環境下,併發讀寫long資料,結果將很神奇。
可見性
當一個執行緒修改了某一個共享變數的值,其他執行緒是否能夠立即知道這個修改。序列程式不需要考慮可見性。
並行程式中,將可能發生問題
某個執行緒修改了某一個全域性變數,其他執行緒不一定能立刻知曉改動。
因為執行緒之間操作不可見
下側的程式碼在執行時,看起來沒什麼問題,
public void T1(){
r2 = A;
B = 1;
}
public void T2(){
r1 = B;
A = 2;
}
重排後
A=2
r2=A=2;
B=1;
r1=B=1;
有序性
指令重排不保證多執行緒之間的有序,只能保證本執行緒內語義一致。
類似上面的程式碼,指令重排將可能導致多執行緒之間操作邏輯錯誤。
不能指令重排的規則:Happen-Before規則
- 程式順序原則
- volatile規則
- 鎖規則
- 傳遞性
- 執行緒的start()方法優於每一個動作
- 執行緒所有操作先於執行緒的終結
- 執行緒中斷先於被中斷的程式碼
- 物件的建構函式執行、結束先於finalize()方法
Happen-Before規則主要保證指令重排不會破壞原有的語義結構
併發級別
Created: Aug 6, 2020 9:40 PM
Tags: 無等待, 無鎖, 阻塞, 飢餓
由於臨界區的存在,多執行緒之間併發必須受到控制。
根據控制併發的策略,將併發的級別進行分類,大致分為阻塞、無飢餓、無鎖、無等待幾種
阻塞
在其他執行緒釋放資源前,當前執行緒無法繼續執行。
使用synchronized關鍵字或重入鎖。
無飢餓
非公平的鎖