![](/img/trans.png)
[英]In java, when variables such as Long, long, Double ,double are autoboxing or unboxing, is reading or writing operation atomic?
[英]Writing long and double is not atomic in Java?
讀取和寫入單個變量是原子的(語言保證!),除非變量是 long 或 double 類型。
我正在閱讀一門課程的幻燈片,我發現它已經寫好了。 這門課是關於並發的。
誰能向我解釋為什么寫 long 或 double 不是原子操作? 着實讓我大吃一驚。
它不是原子的,因為它是機器代碼級別的多步驟操作。 也就是說,longs 和 doubles 比處理器的字長要長。
只是為了澄清 Java 的情況,除非聲明為volatile
否則不會以原子方式讀取或寫入雙精度型和長型
Java long 和 double 在 32 位機器中不是原子的,而是在帶有一些 64 位 JVM 的 64 位機器中是原子的。 為什么它依賴於機器位長度? 因為 32 位機器需要兩次寫入 long(因為 long 是 64 位)。 閱讀本文了解詳細信息。
很多程序員在實踐java並發中的“3.1.2.非原子64位操作”中的這句話想必都看過了。 我已經提到了最新的 JLS 17.7。 double 和 long 的非原子處理。 如今,他們仍然沒有聲稱 64 位 JVM 是常態。 因此,64 位操作被分解為 32 位操作,這些操作破壞了原子性,並且在聲明 volatile 之前在多線程環境中使用是危險的。 Long 和 double 在 java 中是 64 位長。 所以寫和讀操作在java中不是原子的。
Java 編程語言內存模型,對非易失性 long 或 double 值的單次寫入被視為兩次單獨的寫入:一次寫入每個 32 位一半。 這可能導致線程從一次寫入中看到 64 位值的前 32 位,而從另一次寫入中看到后 32 位的情況。
閱讀 maaartinus 的回答@Java 中的哪些操作被認為是原子的?
閱讀 Jon Skeet 的回答@ 當原始數據類型在 Java 中不是線程安全的?
根據JLS,您可以通過將 double 和 long 聲明為 volatile 來使讀和寫操作成為原子操作。 但這並不能確保 ++ 是原子的。 這需要 concurrent.atomic 包。
閱讀 Louis Wasserman 的回答。
還有這個博客和評論。
原子變量操作意味着任何線程都可以讀取/寫入它而不會產生任何垃圾
由於硬件限制,非long
/ double
讀/寫對於 x32 和一些x64 是atomic
的。 如果使用volatile
,它會使其/添加到atomic
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.