簡體   English   中英

這種檢測心跳線程安全且一致嗎?

[英]Is this way of detecting heartbeats threadsafe and consistent?

這個問題必須在兩個博客文章討論( http://dow.ngra.de/2008/10/27/when-systemcurrenttimemillis-is-too-slow/http://dow.ngra.de/2008/10 / 28 /我們真正知道的關於非阻塞並發性的java / ),但我還沒有聽到確定的答案。 如果我們有一個線程執行此操作:

public class HeartBeatThread extends Thread {
  public static int counter = 0;
  public static volatile int cacheFlush = 0;

  public HeartBeatThread() {
    setDaemon(true);
  }

  static {
    new HeartBeatThread().start();
  }

  public void run() {   
    while (true) {     
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }

      counter++;
      cacheFlush++;
    }
  }
}

許多客戶運行以下內容:

if (counter == HeartBeatThread.counter) return;
counter = HeartBeatThread.cacheFlush;

是不是線程安全?

在java內存模型中? 不,你不行。

我已經看到了許多嘗試朝着像這樣的非常“軟沖洗”的方法,但沒有明確的圍欄,你肯定會玩火。

'發生在'之前的語義

http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7

開始在17.4.2結束時將純粹的線程間行為稱為“行動”。 這引起了很多混亂,因為在此之前他們區分了線程間和線程內的操作。 因此,操作計數器的線程內操作沒有通過發生在之前的關系在易失性動作上明確地同步。 你有兩個關於同步的推理線程,一個管理局部一致性,並且受到別名分析的所有好技巧的影響,等等,用於混洗操作另一個是關於全局一致性,僅為線程間操作定義。

一個用於線程內邏輯,在線程內表示讀取和寫入一致地重新排序,一個用於線程間邏輯,表示諸如易失性讀/寫之類的事情以及同步開始/結束被適當地隔離。

問題是非易失性寫入的可見性未定義,因為它是一個線程內操作,因此不在規范中。 它運行的處理器應該能夠看到它,因為它是連續執行這些語句的,但是它的線程間序列化可能是未定義的。

現在,這是否會影響你的現實完全是另一回事。

在x86和x86-64平台上運行java時? 從技術上講,你處於陰暗的區域,但實際上非常強大的保證x86對讀取和寫入的保證,包括對cacheflush訪問的讀/寫總順序以及兩次寫入的本地排序和兩次讀取應啟用此代碼正確執行只要它通過編譯器不受干擾。 這假設編譯器沒有介入並嘗試使用標准下允許的自由來重新排序對您的操作,因為兩個內部線程操作之間可證明缺少別名。

如果你移動到像ia64這樣的弱發布語義的內存? 然后你就自己回來了。

但是,編譯器可以完全真誠地在任何平台上破解java中的程序。 它現在起作用是標准的當前實現的工件,而不是標准的工件。

順便說一句,在CLR中,運行時模型更強大,這種技巧是合法的,因為每個線程的單個寫入都具有有序可見性,因此請務必嘗試從那里翻譯任何示例。

好吧,我認為不是。

第一個if語句:

if (counter == HeartBeatThread.counter) 
    return;

不訪問任何volatile字段且未同步。 因此,您可能會永遠讀取陳舊數據,並且永遠無法訪問volatile字段。

引用第二篇博客文章中的一條評論:“線程A在寫入易失性字段f時可見的任何內容在讀取f時都會顯示給線程B.” 但在你的情況下,B(客戶端)永遠不會讀取f(= cacheFlush)。 因此,對HeartBeatThread.counter的更改不必對客戶端可見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM