关于Java自增操作的原子性

发表于:2012-5-24 09:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Kevin wurr707    来源:51Testing软件测试网采编

  最近在工作中和一个同事因为自增是不是原子性操作争论的面红耳赤,那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中自增不是原子性操作,它包含一个读操作和一个写操作。

  2、以上可能还不能让你信服,要想让人心服口服,就必须用代码说话。正如FaceBook的文化一样:代码赢得争论。那我们就看一段代码:

  以下的代码是用100个线程同时执行自增操作,每个线程自增100次,如果自增操作是原子性操作的话,那么执行完amount的值为10,000。运行代码之后,你会发现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.     }  
  39. }

  3、如果以上还不能让你信服的话,也没关系。我们就把自增操作反编译出来,看看java字节码是怎么操作的

  以下是一个简单的自增操作代码

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

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号