int变量操作与线程安全


今天人人的笔试题目中有一个int i=0;i=i++;是否是线程安全的?如果不是说出在JVM中的执行步骤,以及使用JDK的什么类能够使线程安全些? JDk中的类是AtomicInteger,我答个Integer,哎,悲剧。

 

    文章出处:http://blog.sina.com.cn/s/blog_0d37403b0100xz0t.html

 

    AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。 来看AtomicInteger提供的接口。

 

Java代码   收藏代码
  1. //获取当前的值  
  2.   
  3. public final int get()  
  4.   
  5. //取当前的值,并设置新的值  
  6.   
  7.  public final int getAndSet(int newValue)  
  8.   
  9. //获取当前的值,并自增  
  10.   
  11.  public final int getAndIncrement()  
  12.   
  13. //获取当前的值,并自减  
  14.   
  15. public final int getAndDecrement()  
  16.   
  17. //获取当前的值,并加上预期的值  
  18.   
  19. public final int getAndAdd(int delta)  
  20.   
  21. ... ...  
  22.   
  23. 我们在上一节提到的CAS主要是这两个方法  
  24.   
  25.     public final boolean compareAndSet(int expect, int update) {  
  26.     return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  
  27.     }  
  28.   
  29.     public final boolean weakCompareAndSet(int expect, int update) {  
  30.     return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  
  31.     }  

 

    这两个方法是名称不同,但是做的事是一样的,可能在后续的java版本里面会显示出区别来。

详细查看会发现,这两个接口都是调用一个unsafe的类来操作,这个是通过JNI实现的本地方法,细节就不考虑了。

 

下面是一个对比测试,我们写一个synchronized的方法和一个AtomicInteger的方法来进行测试,直观的感受下性能上的差异

 

Java代码   收藏代码
  1. package zl.study.concurrency;     
  2. import java.util.concurrent.atomic.AtomicInteger;     
  3. public class AtomicIntegerCompareTest {     
  4.     private int value;     
  5.          
  6.     public AtomicIntegerCompareTest(int value){     
  7.         this.value = value;     
  8.     }     
  9.          
  10.     public synchronized int increase(){     
  11.         return value++;     
  12.     }     
  13.          
  14.     public static void main(String args[]){     
  15.         long start = System.currentTimeMillis();     
  16.              
  17.         AtomicIntegerCompareTest test = new AtomicIntegerCompareTest(0);     
  18.         for( int i=0;i< 1000000;i++){     
  19.             test.increase();     
  20.         }     
  21.         long end = System.currentTimeMillis();     
  22.         System.out.println("time elapse:"+(end -start));     
  23.              
  24.         long start1 = System.currentTimeMillis();     
  25.              
  26.         AtomicInteger atomic = new AtomicInteger(0);     
  27.              
  28.         for( int i=0;i< 1000000;i++){     
  29.             atomic.incrementAndGet();     
  30.         }     
  31.         long end1 = System.currentTimeMillis();     
  32.         System.out.println("time elapse:"+(end1 -start1) );     
  33.              
  34.              
  35.     }     
  36. }     
  37. 结果  
  38.   
  39. time elapse:31  
  40. time elapse:16  

 

 

    由此不难看出,通过JNI本地的CAS性能远超synchronized关键字


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM