3 回答

TA貢獻1998條經驗 獲得超6個贊
你不能保證close()
?之前發生?write()
。
你有volatile closed
各種各樣的信號量。你可以用它來發出事件信號,但你不應該用它來保證互斥。在您的情況下,線程 A可以向線程 B發出信號(A 正在寫入,B 從volatile
變量讀?。┑?strong>線程 A無法從線程 B接收信號,這會導致下面描述的問題情況。
volatile
僅保證讀取將看到最近的寫入,但不保證您的寫入將在讀取之前發生。
有問題的情況:
線程 B可能在線程 A翻轉write()
并繼續執行的過程中。closed = true
close()
通過保護整個執行來使用顯式鎖定write()
,并使用相同的鎖來確保您close()
在寫入時不會調用。

TA貢獻1803條經驗 獲得超3個贊
基本上你在這里需要的是一個命令,即write
statement executed before close()
。
Volatile 無濟于事,因為它只是將變量直接寫入內存。
close()
它對聲明沒有任何規定同步關鍵字只是防止另一個線程進入另一個/同一個同步塊,在同一個監視器上同步。如果兩個任務都必須由不同的線程完成,則再次不適合訂購。
在 Kotlin 中解決這個問題的一個非常簡單的例子(java 將是類似的)。您創建一個可用于鎖定的對象。
您的關閉線程
A
將等待獲取 Object 的鎖lock
另一個線程
B
不會等待獲得鎖。相反,它將關閉并通知所有線程完成它們的工作。A 現在可以進入臨界區,
close()
并再次釋放鎖。
val lock = Object()
val A = Thread{
synchronized(lock) {
lock.wait()
closed = true; // closed is a volatile variable
close();
lock.notifyAll()
}
}
val B = Thread{
synchronized(lock) {
write()
lock.notifyAll()
}
}
t.start()
t1.start()
t.join()
t1.join()
請注意,此方法存在很大缺陷,是讓您步入正軌的基本示例。您可能想要使用可重入鎖,并在您的完整代碼中仔細考慮。
添加回答
舉報