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

關(guān)于Java自增操作的原子性

開發(fā) 后端
最近在工作中和一個(gè)同事因?yàn)樽栽鍪遣皇窃有圆僮鳡幷摰拿婕t耳赤,那Java的自增操作到底是不是原子性操作呢,答案是否的,即Java的自增操作不是原子性操作。

最近在工作中和一個(gè)同事因?yàn)樽栽鍪遣皇窃有圆僮鳡幷摰拿婕t耳赤,那Java的自增操作到底是不是原子性操作呢,答案是否的,即Java的自增操作不是原子性操作。

1.首先我們先看看Bruce Eckel是怎么說的:

In the JVM an increment is not atomic and involves both a read and a write. (via the latest Java Performance Tuning Newsletter)

意思很簡單,就是說在jvm中自增不是原子性操作,它包含一個(gè)讀操作和一個(gè)寫操作。

2.以上可能還不能讓你信服,要想讓人心服口服,就必須用代碼說話。正如FaceBook的文化一樣:代碼贏得爭論。那我們就看一段代碼:

以下的代碼是用100個(gè)線程同時(shí)執(zhí)行自增操作,每個(gè)線程自增100次,如果自增操作是原子性操作的話,那么執(zhí)行完amount的值為10,000。運(yùn)行代碼之后,你會(huì)發(fā)現(xiàn)amount的值小于10,000,這就說明自增操作不是原子性的

  1. /**  
  2.  *   
  3.  * @author renrun.wu  
  4.  */ 
  5. public class MultiThread implements Runnable {  
  6.     private int count;  
  7.     private int amount = 1;  
  8.       
  9.     public MultiThread() {  
  10.          count = 100;  
  11.     }  
  12.       
  13.     public MultiThread(int count) {  
  14.         this.count = count;  
  15.     }  
  16.       
  17.     @Override 
  18.     public void run() {  
  19.         for (int i = 0; i < count; i++) {  
  20.             amount++;  
  21.         }  
  22.     }  
  23.       
  24.     public static void main(String[] args) {  
  25.         ExecutorService executorService = Executors.newCachedThreadPool();  
  26.         MultiThread multiThread =new MultiThread();  
  27.         for (int i = 0; i < 100; i++) {  
  28.             executorService.execute(multiThread);  
  29.         }  
  30.         executorService.shutdown();  
  31.           
  32.         try {  
  33.             Thread.sleep(60000);  
  34.         } catch (InterruptedException e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.         System.out.println(multiThread.amount);  
  38.     }  

3.如果以上還不能讓你信服的話,也沒關(guān)系。我們就把自增操作反編譯出來,看看java字節(jié)碼是怎么操作的

以下是一個(gè)簡單的自增操作代碼

  1. public class Increment {  
  2.     private int id = 0;  
  3.  
  4.     public void getNext(){  
  5.         id++;  
  6.     }  

我們看看反編譯之后的Java字節(jié)碼,主要關(guān)注getNext()方法內(nèi)部的Java字節(jié)碼。

  1. public class Increment extends java.lang.Object{  
  2.     public Increment();  
  3.       Code:  
  4. :   aload_0  
  5. :   invokespecial   #1//Method java/lang/Object."<init>":()V  
  6. :   aload_0  
  7. :   iconst_0  
  8. :   putfield        #2//Field id:I  
  9. :   return 
  10.  
  11.     public void getNext();  
  12.       Code:  
  13. :   aload_0         //加載局部變量表index為0的變量,在這里是this   
  14. :   dup                 //將當(dāng)前棧頂?shù)膶?duì)象引用復(fù)制一份  
  15. :   getfield        #2//Field id:I,獲取id的值,并將其值壓入棧頂  
  16. :   iconst_1            //將int型的值1壓入棧頂  
  17. :   iadd                //將棧頂兩個(gè)int類型的元素相加,并將其值壓入棧頂  
  18. :   putfield        #2//Field id:I,將棧頂?shù)闹蒂x值給id  
  19. :  return 
  20.  
  21.     } 

很明顯,我們能夠看到在getNext()方法內(nèi)部,對(duì)于類變量id有一個(gè)先取值后加一再賦值的過程。因此,我們可以很肯定的說Java中的自增操作不是原子性的。

4.也許你會(huì)問,那局部變量的自增操作是否是原子性的。好,我們在看看一下代碼:

  1. public class Increment {  
  2.     public void getNext(){  
  3.     int id = 0;  
  4.         id++;  
  5.     }  

我們再看看反編譯之后的Java字節(jié)碼,主要還是關(guān)注getNext()方法內(nèi)部的Java字節(jié)碼。

  1. public class Increment extends java.lang.Object{  
  2. public Increment();  
  3.   Code:  
  4. :   aload_0  
  5. :   invokespecial   #1//Method java/lang/Object."<init>":()V  
  6. :   return 
  7.  
  8. public void getNext();  
  9.   Code:  
  10. :   iconst_0  
  11. :   istore_1  
  12. :   iinc    11 
  13. :   return 
  14.  

與全局變量的自增操作相比,很明顯局部變量的自增操作少了getfield與putfield操作。而且對(duì)于局部變量來說,它無論如何都不會(huì)涉及到多線程的操作,因此局部變量的自增操作是否是原子操作也就顯得不那么重要了。

原文鏈接:http://www.cnblogs.com/kevinwu/archive/2012/05/02/2479464.html

責(zé)任編輯:林師授 來源: wurr707的博客
相關(guān)推薦

2023-01-05 12:30:32

Redis

2021-09-22 12:56:19

編程技能Golang

2022-08-21 17:35:31

原子多線程

2023-12-26 01:09:28

MySQL存儲(chǔ)釋放鎖

2020-08-24 07:19:13

主鍵自增數(shù)據(jù)庫

2014-01-09 09:45:41

原子飛原子

2010-04-30 12:15:42

Oracle自增ID

2010-07-09 12:49:41

SQL Server自

2021-06-02 16:30:33

PolarDB原子性數(shù)據(jù)庫

2011-03-21 12:58:26

Oracle自增字段

2021-06-03 14:00:35

PolarDB

2010-04-26 11:55:48

Oracle自增字段

2010-09-28 16:14:14

SQL Server自

2009-09-24 13:49:31

Hibernate自增

2010-04-09 09:28:30

Oracle自增字段

2021-11-01 15:35:31

C++自增自減

2023-11-07 08:04:19

Go并發(fā)程序原子操作

2010-03-29 14:09:12

Oracle ID 自

2010-10-20 10:04:36

sql server自

2010-10-08 15:42:39

MySQL設(shè)置自增字段
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 精品欧美一区二区在线观看欧美熟 | 亚洲免费福利视频 | 播放一级毛片 | jⅰzz亚洲| 搞av.com| 日韩欧美成人精品 | 久久综合狠狠综合久久综合88 | 亚洲色在线视频 | 亚洲精品国产第一综合99久久 | 精品久久久久久久久久久久久久 | 一区二区三区免费 | 日本亚洲一区二区 | 久久久久久久综合色一本 | 国产在线一区二区三区 | 色综合久久天天综合网 | 成人国产在线视频 | 久久久久亚洲精品 | 久久久免费电影 | av片网| 精品欧美一区二区精品久久久 | 日韩精品在线一区 | 人人爽人人爽人人片av | 亚洲成人免费视频 | 超碰在线97国产 | 精品国产乱码久久久久久1区2区 | 欧美性生活免费 | 国产精品久久久久久久久久久久久久 | 99在线视频观看 | 亚洲激精日韩激精欧美精品 | 成人在线免费电影 | 性在线 | 成人一区二区在线 | 午夜精品一区 | 韩国精品在线观看 | www.日本国产 | 精品日韩在线观看 | 久久久国产一区 | 亚洲国产成人精品女人久久久 | 尤物在线 | 欧美成人精品一区二区三区 | 婷婷免费视频 |