亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 volatile 變量確保關閉操作后永遠不會執行寫操作?

如何使用 volatile 變量確保關閉操作后永遠不會執行寫操作?

慕田峪7331174 2023-03-31 09:14:02
考慮以下代碼:Thread A:closed = true; // closed is a volatile variableclose();Thread B:while(true){  if(!closed){    write();  }  else {    ...  }}如果我沒理解錯的話,closed = true;happens-beforeclose();和closed = true;happens-before ,但是和write();之間好像沒有 happens-before 關系。close();write();上面的代碼是否確保write();只會在之前被調用close()?如果沒有,可以進行哪些修改以使其工作?還是我必須使用synchronized?
查看完整描述

3 回答

?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

你不能保證close()?之前發生?write()

你有volatile closed各種各樣的信號量。你可以用它來發出事件信號,但你不應該用它來保證互斥。在您的情況下,線程 A可以向線程 B發出信號(A 正在寫入,B 從volatile變量讀?。┑?strong>線程 A無法從線程 B接收信號,這會導致下面描述的問題情況。

volatile僅保證讀取將看到最近的寫入,但不保證您的寫入將在讀取之前發生。

有問題的情況:

線程 B可能在線程 A翻轉write()并繼續執行的過程中。closed = trueclose()

通過保護整個執行來使用顯式鎖定write(),并使用相同的鎖來確保您close()在寫入時不會調用。


查看完整回答
反對 回復 2023-03-31
?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

你已經給出了答案:“還是我必須使用同步?” 是的!



查看完整回答
反對 回復 2023-03-31
?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

基本上你在這里需要的是一個命令,即writestatement executed before close()

  1. Volatile 無濟于事,因為它只是將變量直接寫入內存。close()它對聲明沒有任何規定

  2. 同步關鍵字只是防止另一個線程進入另一個/同一個同步塊,在同一個監視器上同步。如果兩個任務都必須由不同的線程完成,則再次不適合訂購。

在 Kotlin 中解決這個問題的一個非常簡單的例子(java 將是類似的)。您創建一個可用于鎖定的對象。

  1. 您的關閉線程A將等待獲取 Object 的鎖lock

  2. 另一個線程B不會等待獲得鎖。相反,它將關閉并通知所有線程完成它們的工作。

  3. 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()


請注意,此方法存在很大缺陷,是讓您步入正軌的基本示例。您可能想要使用可重入鎖,并在您的完整代碼中仔細考慮。


查看完整回答
反對 回復 2023-03-31
  • 3 回答
  • 0 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號