1. 程式人生 > >多執行緒1:AtomicInteger的使用,多執行緒疊加或疊減

多執行緒1:AtomicInteger的使用,多執行緒疊加或疊減

  1. import java.util.concurrent.atomic.AtomicInteger;  
  2. publicclass AtomicIntegerTest {  
  3.     public AtomicInteger inc = new AtomicInteger();  
  4.     publicvoid increase() {  
  5.         inc.getAndIncrement();//i++操作
  6.         //inc.getAndDecrement();//i--操作
  7.     }  
  8.     publicstaticvoid main(String[] args) {  
  9.         final
     AtomicIntegerTest test = new AtomicIntegerTest();  
  10.         for (int i = 0; i < 10; i++) {  
  11.             new Thread() {  
  12.                 publicvoid run() {  
  13.                     for (int j = 0; j < 1000; j++)  
  14.                         test.increase();  
  15.                 };  
  16.             }.start();  
  17.         }  
  18.         while (Thread.activeCount() > 1)  
  19.             // 保證前面的執行緒都執行完
  20.             Thread.yield();  
  21.         System.out.println(test.inc);  
  22.     }  
  23. }  

 可以發現結果都是10000,也就是說AtomicInteger是執行緒安全的。

值得一看。

這裡,我們來看看AtomicInteger是如何使用非阻塞演算法來實現併發控制的。

AtomicInteger的關鍵域只有一下3個:

  1. // setup to use Unsafe.compareAndSwapInt for updates  
  2. privatestaticfinal Unsafe unsafe = Unsafe.getUnsafe();    
  3. privatestaticfinallong valueOffset;    
  4. privatevolatileint value;    

這裡, unsafe是Java提供的獲得對物件記憶體地址訪問的類,註釋已經清楚的寫出了,它的作用就是在更新操作時提供“比較並替換”的作用。實際上就是AtomicInteger中的一個工具。

valueOffset是用來記錄value本身在記憶體的便宜地址的,這個記錄,也主要是為了在更新操作在記憶體中找到value的位置,方便比較。

注意:value是用來儲存整數的時間變數,這裡被宣告為volatile,就是為了保證在更新操作時,當前執行緒可以拿到value最新的值(併發環境下,value可能已經被其他執行緒更新了)。

這裡,我們以自增的程式碼為例,可以看到這個併發控制的核心演算法:

  1. /** 
  2. * Atomically increments by one the current value. 
  3. * 
  4. * @return the updated value 
  5. */
  6. publicfinalint incrementAndGet() {  
  7. for (;;) {  
  8. //這裡可以拿到value的最新值
  9. int current = get();  
  10. int next = current + 1;  
  11. if (compareAndSet(current, next))  
  12. return next;  
  13. }  
  14. }  
  15. publicfinalboolean compareAndSet(int expect, int update) {  
  16. //使用unsafe的native方法,實現高效的硬體級別CAS
  17. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  
  18. }  

 好了,看到這個程式碼,基本上就看到這個類的核心了。相對來說,其實這個類還是比較簡單的。可以參考http://hittyt.iteye.com/blog/1130990