關於i 引出的執行緒不安全性的分析以及解決措施

2022-02-01 03:21:52 字數 623 閱讀 6847

q:i++是執行緒安全的嗎?

a:如果是區域性變數,那麼i++是執行緒安全。

如果是全域性變數,那麼i++不是執行緒安全的。

理由:如果是區域性變數,那麼i++是執行緒安全:區域性變數其他執行緒訪問不到,所以根本不存在是否安全這個問題。

如果是全域性變數,那麼i++不是執行緒安全的:當它是全域性變數時,所有執行緒都可以訪問,那麼,當有1000個執行緒同時執行i++操作時,i變數的副本拷貝到每個執行緒的執行緒棧,當同時有兩個執行緒以上的執行緒讀取執行緒變數,比如此時是5,那麼同時執行i++操作,再寫入到全域性變數,最後,兩個執行緒跑完了,這個i還是6,而並不會是7,所以,出現不安全性。

從更底層的角度講,主要是因為i++這個操作不是原子性的,這個會編譯成count = count +1; 所以會出現多執行緒訪問衝突問題。volatile雖然可以保證多執行緒對修改可見,但**中用到了

count++, 主要是count++不是原子性操作,這個會編譯成count = count +1,其實是做了3個步驟,乙個是讀取,修改,寫入 。所以會出現多執行緒訪問衝突問題

總而言之,如果操作是原子性的,也就是說轉為彙編語句是一句,不可分割的,那麼無論怎樣都是執行緒安全的,否則,不管加沒加volatile,都是執行緒不安全的!

解決方案:i前面加上atomicinteger

hashmap的執行緒不安全性

首先hashmap在多個執行緒同時對其操作的時候造成的髒讀很統一理解,比如乙個執行緒a對hashmap進行讀操作,乙個執行緒b對hashmap就行寫操作。執行緒b先進入put方法中,此時還沒有寫資料的時候執行緒a輪轉執行,並一直執行到結束,假設執行取到資料為條,這時執行緒b繼續執行新增了一條資料。那...

scanf函式的不安全性分析

int scanf char 是其函式宣告。其中只要求第乙個引數是char 即字串即可,而對於其他引數則沒有限制型別和個數,這其中有安全風險。舉個例子 scanf d c i,ch 如果從鍵盤上輸入的資料是 30 a?則變數ch的值是空格字元而不是字元 a 這種錯誤很隱蔽,因此建議讀者盡量不要使用s...

gets 函式的不安全性

在linux下編譯c檔案時出現 warning the gets function is dangerous and should not be used問題在於gets 函式在獲取輸入時,不會對輸入有檢查,如果無限輸入會造成棧空間溢位,在程式返回時,不能正常的找到返回位址,程式將發生不可 行為。使...