java執行緒安全問題產生的原因
最近工作中遇到不少多執行緒問題,但自己一直對多執行緒的理解比較表層。沒有深入探究。正是最近工作中遇到的問題,致使我深入的去了解多執行緒安全問題為什麼會產生。
多執行緒使我們的計算機可以同時執行多個程式,感覺很美好。
but,多執行緒的安全問題,到底怎麼回事,到底怎麼來的,對於有點理想主義的我來說這簡直就是BUG。
網上有不少介紹多執行緒產生的原因的。我大致看了一遍,感覺都介紹的太粗線條,可能不太適合經驗不足者理解。
so,我就自己整理一下我自己的理解。如有謬誤歡迎大家指正和交流。
首先java 虛擬機器中 記憶體區域分為執行緒共享和執行緒私有的兩大類。
現場 畫圖哈哈。
java虛擬機器在執行位元組碼指令的時候是什麼情況呢?
假設int 型別資料a線上程共享區域目前值為0,java執行以下程式碼時,需要經過哪些操作呢?
public class Test001
{
public int a = 0;
public void dosomething(){
a ++ ;
}
}
我寫了一個java類,編譯一下
執行命令javap -l -v Test001.class
我得到了如下結果
這個是主要執行自增的位元組碼指令,我們來看下執行過程;
0:將物件本身入棧,這裡隱含第一個引數為this;
1:複製棧頂元素,也就是物件的引用;
2:獲取棧頂物件屬性a的值,並將其入棧;
5:將int型1推送至棧頂;
6:將棧頂兩個int型別資料相加,並將結果入棧;
7:將棧頂的值放入物件屬性a中;
10:return,不用解釋了
我們可以看到簡單的一個自增操作,虛擬機器要執行的指令卻不止一個。
在這一組指令執行過程中,cpu是有可能切換執行緒的,如果在當前執行緒t1被掛起之後其他執行緒修改了這個物件的a屬性值,那麼恢復執行緒執行時t1執行緒將會覆蓋其他執行緒已經修改過的值。
所以,,執行緒安全問題就是這麼產生的了。
理解了怎麼產生的就更容易解決如何避免執行緒安全問題了。