竟態指計算結果的正確性依賴相對時間順序和執行緒的交錯,通俗的說就是計算結果與時間有關,對於乙個同樣的輸入,有時候結果正確,有時候結果不正確。
竟態不一定會導致結果錯誤,只是說有這種導致結果出錯的可能性。
下面有乙個模擬請求id生成器,讓多個執行緒隨機生成請求id.
public final classview coderequestidgenerator
public
static
requestidgenerator getinstance ()
public
short
nextsequence()
else
return
sequence;
}public
string nextid()
}
測試類:
publicview codeclass
raceconditiondemo
for(thread t : workthreads)
}static
class
workerthread extends thread
@override
public
void
run()
}private
void
processrequest(string requestid) }}
按理說每個執行緒不同時間生成的請求id應該都是不同的,但是多次執行會發現有時候請求id是相同的。
這也就是說執行結果正確與否與時間相關,即出現了竟態。
分析可見nextsequence()這個方法導致了不同的執行緒拿到了相同的requestid,因為requestidgenerator這個類中有乙個共享的全域性變數sequence,多個執行緒併發的讀取更新
sequence導致了竟態的出現。即乙個執行緒對sequence所做的更新可能被其它執行緒的更新而覆蓋掉,導致資料出現髒讀。
即讀取乙個共享變數的值(read),然後根據值做一些計算(modify),最後更新該變數的值(write).
例如sequence++就是如此,過程指令如下:
1.從記憶體中將squence的值讀取到暫存器r1中
2.r1的值加1
3.將r1的值更新到sequence變數的記憶體空間中
在多執行緒環境下,某個執行緒執行完1後,可能其他執行緒已經更新了sequence的值,但是該執行緒卻仍然使用r1未更新的值去操作2,3指令,造成丟失更新和髒讀。
以下面這段**為例:
public檢測而後行動指讀取某個共享變數的值,根據該值做一些判斷,然後根據該判斷結果去條件執行一些操作。short
nextsequence()
else
return
sequence;
}
在多執行緒環境下,可能當某個執行緒執行完步驟1後,其它執行緒更新了sequence的值,此時該執行緒仍然根據之前的判斷去做一些操作,也會造成丟失資料更新和髒讀。
多執行緒程式設計之執行緒取消
關鍵 pthread cancel函式傳送 終止訊號 pthread setcancelstate函式 設定終止方式 pthread testcancel函式取消執行緒 另一功能是 設定取消點 1 執行緒取消的定義 一般情況下,執行緒在其主體函式退出的時候會自動終止,但同時也可以因為接收到另乙個執行...
多執行緒程式設計之執行緒的封裝
前人總結出,乙個執行緒安全的class應當滿足的條件 1.從多個執行緒訪問時,其表現出正確的行為,無論作業系統如何排程這些執行緒,無論這些執行緒的執行順序如何交織。2.呼叫端 無需額外的同步或其他協調動作 在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。使用多執行緒要考慮...
多執行緒程式設計之執行緒的封裝
前人總結出,乙個執行緒安全的class應當滿足的條件 1.從多個執行緒訪問時,其表現出正確的行為,無論作業系統如何排程這些執行緒,無論這些執行緒的執行順序如何交織。2.呼叫端 無需額外的同步或其他協調動作 在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。使用多執行緒要考慮...