成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 中 long 是不是原子操作?

開發 后端
java中基本類型中,long和double的長度都是8個字節,32位(4字節)處理器對其讀寫操作無法一次完成,那么,JVM,long和double是原子性的嗎?來看一下吧。

[[408025]]

 Java中long和double的原子性

java中基本類型中,long和double的長度都是8個字節,32位(4字節)處理器對其讀寫操作無法一次完成,那么,JVM,long和double是原子性的嗎?

JVM中對long的操作是不是原子操作?

首先,通過一段程序對long的原子性進行判斷。測試程序如下: 

  1. public class LongAtomTest implements Runnable {  
  2.     private static long field = 0 
  3.     private volatile long value;  
  4.     public long getValue() { 
  5.          return value;  
  6.     }  
  7.     public void setValue(long value) {  
  8.         this.value = value;  
  9.     }  
  10.     public LongAtomTest(long value) {  
  11.         this.setValue(value);  
  12.     }  
  13.     @Override  
  14.     public void run() {  
  15.         int i = 0 
  16.         while (i < 100000) {  
  17.             LongAtomTest.field = this.getValue();  
  18.             i++;  
  19.             long temp = LongAtomTest.field;  
  20.             if (temp != 1L && temp != -1L) {  
  21.                 System.out.println("出現錯誤結果" + temp);  
  22.                 System.exit(0);  
  23.             }  
  24.         }  
  25.         System.out.println("運行正確");  
  26.     }  
  27.     public static void main(String[] args) throws InterruptedException {  
  28.         // 獲取并打印當前JVM是32位還是64位的  
  29.         String arch = System.getProperty("sun.arch.data.model");  
  30.         System.out.println(arch+"-bit");  
  31.         LongAtomTest t1 = new LongAtomTest(1);  
  32.         LongAtomTest t2 = new LongAtomTest(-1);  
  33.         Thread T1 = new Thread(t1);  
  34.         Thread T2 = new Thread(t2);  
  35.         T1.start();  
  36.         T2.start();  
  37.         T1.join();  
  38.         T2.join();  
  39.     }   

可以看到,程序中有兩條線程t1,t2;t1,t2各自不停的給long類型的靜態變量field賦值為1,-1;t1,t2每次賦值后,會讀取field的值,若field值既不是1又不是-1,就將field的值打印出來。

如果對long的寫入和讀取操作是原子性的,那么,field的值只可能是1或者-1

運行結果如下: 

  1. 32-bit  
  2. 出現錯誤結果-4294967295  
  3. 運行正確 

可以看出,當線程t1,t2同時對long進行寫的時候,long出現了既不是t1寫入的值,又不是t2寫入的值。46 張 PPT 弄懂 JVM 調優,推薦看下。

可以推測,jvm中對long的操作并非原子操作。

為什么對long的操作不是原子的?

JVM內存模型中定義了8中原子操作:

  1.  lock:將一個變量標識為被一個線程獨占狀態
  2.  unclock:將一個變量從獨占狀態釋放出來,釋放后的變量才可以被其他線程鎖定
  3.  read:將一個變量的值從主內存傳輸到工作內存中,以便隨后的load操作
  4.  load:把read操作從主內存中得到的變量值放入工作內存的變量的副本中
  5.  use:把工作內存中的一個變量的值傳給執行引擎,每當虛擬機遇到一個使用到變量的指令時都會使用該指令
  6.  assign:把一個從執行引擎接收到的值賦給工作內存中的變量,每當虛擬機遇到一個給變量賦值的指令時,都要使用該操作
  7.  store:把工作內存中的一個變量的值傳遞給主內存,以便隨后的write操作
  8.  write:把store操作從工作內存中得到的變量的值寫到主內存中的變量

其中,與賦值,取值相關的包括 read,load,use,assign,store,write

按照這個規定,long的讀寫都是原子操作,與我們的實踐結果相反,為什會導致這種問題呢?

對于32位操作系統來說,單次次操作能處理的最長長度為32bit,而long類型8字節64bit,所以對long的讀寫都要兩條指令才能完成(即每次讀寫64bit中的32bit)。

如果JVM要保證long和double讀寫的原子性,勢必要做額外的處理。那么,JVM有對這一情況進行額外處理嗎?另外,JVM 系列面試題和答案全部整理好了,微信搜索Java技術棧,在后臺發送:面試,可以在線閱讀。

針對這一問題可以參考Java語言規范文檔:jls-17 Non-Atomic Treatment of double and long

For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64-bit value from one write, and the second 32 bits from another write.

Writes and reads of volatile long and double values are always atomic.

Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or 64-bit values.

Some implementations may find it convenient to divide a single write action on a 64-bit long or double value into two write actions on adjacent 32-bit values. For efficiency's sake, this behavior is implementation-specific; an implementation of the Java Virtual Machine is free to perform writes to long and double values atomically or in two parts.

Implementations of the Java Virtual Machine are encouraged to avoid splitting 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as volatile or synchronize their programs correctly to avoid possible complications.

從規定中我們可以知道:

  1.  對于64位的long和double,如果沒有被volatile修飾,那么對其操作可以不是原子的。在操作的時候,可以分成兩步,每次對32位操作。
  2.  如果使用volatile修飾long和double,那么其讀寫都是原子操作
  3.  對于64位的引用地址的讀寫,都是原子操作
  4.  在實現JVM時,可以自由選擇是否把讀寫long和double作為原子操作
  5.  推薦JVM實現為原子操作

從程序得到的結果來看,32位的HotSpot沒有把long和double的讀寫實現為原子操作。在讀寫的時候,分成兩次操作,每次讀寫32位。因為采用了這種策略,所以64位的long和double的讀與寫都不是原子操作。

在硬件,操作系統,JVM都是64位的情況下呢?

對于64bit的環境來說,單次操作可以操作64bit的數據,即可以以一次性讀寫long或double的整個64bit。因此我們可以猜測,在64位的環境下,long和double的讀寫有可能是原子操作。在換了64位的JVM之后,多次運行,結果都是正確的 

  1. 64-bit  
  2. 運行正確  
  3. 運行正確 

結果表明,在64bit的虛擬機下,long的處理是原子性的。最后,關注公眾號Java技術棧,在后臺回復:面試,可以獲取我整理的 JVM 系列面試題和答案,非常齊全。 

 

責任編輯:龐桂玉 來源: Java技術棧
相關推薦

2019-02-27 09:28:15

Redis服務器事務

2014-01-09 09:45:41

原子飛原子

2009-09-17 22:20:07

2012-05-23 12:49:58

Java自增操作原子性

2019-05-16 09:23:18

前端Title后端

2015-05-27 11:19:02

云存儲分布式

2023-06-27 08:45:19

原子操作Golang

2019-11-18 21:32:39

Docker容器平臺

2020-11-27 06:44:22

原子加鎖x86

2019-06-06 08:30:07

區塊鏈數字貨幣比特幣

2021-05-28 22:35:57

比特幣加密貨幣BTC

2023-09-24 23:44:10

C++類型安全

2021-11-11 06:57:00

PythonPyPy程序

2012-07-02 09:40:45

小米手機

2019-10-16 18:35:37

Windows操作系統微軟

2021-07-15 23:23:20

垃圾回收器GC

2021-01-11 05:37:54

倉儲模式接口

2020-02-25 16:30:36

MD5是不是加密

2021-05-10 08:32:32

Websocket協議http

2023-07-13 08:26:49

Java羅漢增強類
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人av在线播放 | 91新视频 | 懂色中文一区二区在线播放 | 精品美女久久久 | 国产精品久久av | 精品欧美一区二区中文字幕视频 | 风间由美一区二区三区在线观看 | 国产成人一区二区 | 色综合色综合网色综合 | 久久福利电影 | 亚洲精品一 | 天堂中文字幕av | xnxx 日本免费 | 亚洲激情专区 | 91新视频 | 中文字幕一二三区 | 色综合视频| 国产精品久久久久久影院8一贰佰 | 米奇7777狠狠狠狠视频 | 依人成人| 欧美日韩亚洲国产 | 国产婷婷色综合av蜜臀av | 国产精品区二区三区日本 | 中文精品视频 | 韩日一区 | 在线播放国产一区二区三区 | 日本精品久久 | 在线视频 亚洲 | 国产高清精品在线 | 国产高清视频一区 | 日韩久久精品视频 | 狠狠视频 | 国产精品a久久久久 | 成年免费大片黄在线观看一级 | 国产精品自拍一区 | 国产一区二区三区www | 亚洲码欧美码一区二区三区 | 国产精品久久av | 中文一区二区 | www.99热.com | 欧美在线免费 |