多執行緒程式設計之竟態

2022-09-13 01:00:18 字數 1549 閱讀 1534

竟態指計算結果的正確性依賴相對時間順序和執行緒的交錯,通俗的說就是計算結果與時間有關,對於乙個同樣的輸入,有時候結果正確,有時候結果不正確。

竟態不一定會導致結果錯誤,只是說有這種導致結果出錯的可能性。

下面有乙個模擬請求id生成器,讓多個執行緒隨機生成請求id.

public final class

requestidgenerator

public

static

requestidgenerator getinstance ()

public

short

nextsequence()

else

return

sequence;

}public

string nextid()

}

view code

測試類:

public

class

raceconditiondemo

for(thread t : workthreads)

}static

class

workerthread extends thread

@override

public

void

run()

}private

void

processrequest(string requestid) }}

view code

按理說每個執行緒不同時間生成的請求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.呼叫端 無需額外的同步或其他協調動作 在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。使用多執行緒要考慮...