2013-03-04 52 views

回答

18

我以前的答案是不正確的,因爲通過juancn在評論解釋說:

這是Atomic*類和揮發性訪問的區別。參考分配只是在原子的意義上說,不會發生字撕裂,但沒有可見性或重新排序的保證。對於所有原始類型和引用,Java保證原子寫入在這個限制的意義上,但不保證長/雙(儘管在64位虛擬機中我認爲它們總是原子的)。

以前的答案

這是必要的,主要表現爲compareAndSetgetAndSet方法。否則無法做到這一點(需要2次操作)。

+2

+1這正是所有'Atomic ...'類的原因。 – 2013-03-04 07:30:17

+1

@JimGarrison不完全。 long/float/double賦值不是原子的。它會以任意順序將這兩個單詞分配給它所分配的地址(您將需要查找有關Java內存模型的信息)。如果您有兩個線程競爭爲該地址寫入值,則可以獲取源自線程1的一個單詞,然後源自線程2的第二個單詞,從而導致垃圾值 – searchengine27 2015-02-18 16:41:18

+3

*可*分配給任意的順序。許多硬件平臺都支持64位字寬。並且在這張紙上,這隻適用於長和雙。不是浮動的,這是32位寬。 – 2016-06-29 23:45:04

21

爲什麼如果參考分配是在java中原子使用的AtomicReference?

當創建新值所基於的決定取決於引用的先前值時,您需要它。例如,當實現像數據結構這樣的LinkedList時,你不能將頭部設置爲引用前一個節點的新節點。在讀取前一節點和將頭設置爲新節點之間的時間內,其他一些線程可能同時更新了頭參考的值。如果我們的線程不知道這種變化,它會丟失。

我們需要揮發性有參考分配新建分配FY原子?

操作本身將在執行它的CPU內核上執行原子操作,但不能保證其他內核上的線程在下次讀取時會知道它。

+1

此外,寫入引用始終是原子的,取自JLS:寫入和讀取引用總是原子的,無論它們是以32位還是64位值實現的。 – SakeSushiBig 2013-03-04 16:50:44

+0

+1。我認爲你的答案很好,但是展示AtomicReference類如何發揮你所提供的例子會更好。 – nhahtdh 2013-03-21 18:54:07

+0

檢查此鏈接:http://stackoverflow.com/questions/31042696/when-does-a-reference-need-to-be-atomic?noredirect=1&lq=1 – 2016-12-25 13:39:07

2

的原因是,即使引用是原子,它是在一個非常狹義的原子。

如果一個線程寫入非易失性的參考,有什麼保證的是,其他線程會看到整個寫或不看它在所有(無字撕裂/垃圾)。

但在任何時候都不能保證任何其他線程將永遠不會看到它也不會看到它們將以相同的順序被看到。

AtomicReference提供更強大的保障(除了CAS操作),本質上他們表現得像揮發性:

  • ,在線程A發生了性寫之前的任何寫入後續的揮發性讀取後在線程B可見的變量
  • 易失操作無法重新排序