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

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

Java - CountDownLatch.await() 可以由編譯器重新排序嗎

Java - CountDownLatch.await() 可以由編譯器重新排序嗎

縹緲止盈 2024-01-05 17:05:19
我必須在不同的系統上調用操作。另一個系統是高并發、分布式的。因此我通過 MessageBus 集成它。需要一種實現來讓調用者等待,直到在總線上收到結果或超時到期。實現包括三個步驟:首先,我必須將 future 和 CountDownLatch(一旦收到結果就釋放)打包到 ConcurrentHashMap 中。該映射與偵聽 MessageBus 的組件共享。然后我必須開始執行并最后等待閂鎖。public FailSafeFuture execute(Execution execution,long timeout,TimeUnit timeoutUnit) {    //Step 1    final WaitingFailSafeFuture future = new WaitingFailSafeFuture();    final CountDownLatch countDownLatch = new CountDownLatch(1);    final PendingExecution pendingExecution = new PendingExecution(future, countDownLatch);    final String id = execution.getId();    pendingExecutions.put(id, pendingExecution); //ConcurrentHashMap shared with Bus    //Step 2    execution.execute();    //Step 3    final boolean awaitSuccessfull = countDownLatch.await(timeout, timeoutUnit);    //...    return future;}所以問題是:編譯器可以對這 3 個步驟重新排序嗎?據我了解,只有步驟1和步驟3形成了發生之前的關系。因此理論上,第 2 步可以由編譯器自由移動。是否可以將步驟 2 移到等待后面,從而使代碼無效?后續問題:用共享對象上的等待/通知組合替換 CountDownLatch 是否可以解決問題而無需進一步同步(當然不考慮超時)
查看完整描述

1 回答

?
一只名叫tom的貓

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

如果最終結果保持不變(就編譯器的想法而言),則可能會發生指令重新排序,并且如果涉及多個線程,則可能需要額外的同步(因為編譯器不知道其他線程可能期望特定的順序)。

在單個線程中,如您的示例所示,所有步驟都相互關聯happens-before。即使編譯器可以重新排序這些方法調用,最終結果也需要相同(execute()之前調用await())。由于await()涉及同步,execute()除非您使用有錯誤的瘋狂實現,否則不可能以某種方式在它之后滑動。

happens-before之間的關系確保代碼在代碼執行之前發生。所以顯示的代碼沒有任何問題。countDown()await()PendingExecutionawait()

您應該始終更喜歡這些java.util.concurrentwait/notify,因為它們更易于使用并且提供更多功能。


查看完整回答
反對 回復 2024-01-05
  • 1 回答
  • 0 關注
  • 132 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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