[英]Java thread safe counter own lock implementation
我只是想過如何在從不同線程修改變量時鎖定諸如int之類的變量。 我不會以這種方式使用它,而且我了解Java中的synced關鍵字,但是我想了解這一點以及它一般如何工作。
這就是我的代碼:
private int i = 0;
private int lock = 0;
public void count(int lock) {
while (true) {
if (this.lock == 0) {
this.lock = lock;
}
if (this.lock == lock) {
i ++;
this.lock = 0;
return;
}
}
}
問題:行得通嗎? 這個計數器線程安全嗎? 如果是,則:synced關鍵字是否是類似的工作? 如果否:為什么不呢?
編輯:我忘了提到每個線程使用不同的鎖值調用count方法。
簡短的答案是,“不”不能保證那里的線程安全。
更長的答案是您需要查看Java內存模型以了解原因。 問題的部分原因是不同的線程可能無法同時看到更改。 內存模型僅保證寫后的讀取在執行寫操作的同一線程中看到更新的值,除非跨越了內存屏障。 另一個線程即使在另一個線程執行了寫操作之后執行了讀取操作,也可能看不到該更新。 除非您使用volatile
關鍵字描述變量。 或使用synchronized
關鍵字來確保只有一個線程在更新該值。 這種行為使Java運行時可以優化代碼,可能是通過在循環中內聯它注意到的東西來保持不變,並且還可以使用本機匯編語言,該語言不提供同步保證,但可以證明更快。
問題的另一部分是,當兩個更新同時發生在不同線程上時,確保對兩個線程可用相同結果的唯一方法是使用相應的低級匯編語言指令-這可能是稱為compareAndSet,compareAndSwap或testAndSet。
因此,去編寫您編寫的代碼,完全可以實現這種執行順序的等效功能(其中T1和T2為單獨的線程)...
// assuming i begins at 0.
T1: if this.lock == true
T2: if this.lock == true
T1: this.lock = lock
T1: if this.lock == lock // evaluates to true
T2: if this.lock == lock // evaluates to true
T1: this.lock = lock
T2: this.lock = lock
實際上,它更加復雜,因為您不能說每個指令都是CPU上的單個指令。 從根本上講,您可以讓兩個線程同時執行某種更新,所有伴隨的結果都是兩次更新或丟失。
甚至更簡單的答案:將java.util.concurrent
提供的Atomic原語用於線程安全計數器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.