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