1. 程式人生 > >volatile與AtomicIntegerfieldupdater 區別與關係

volatile與AtomicIntegerfieldupdater 區別與關係

volatile 實現了多執行緒的可見性,用於多執行緒對某個變數的修改 比如bool 值的變化,別的執行緒立即看到,可以退出迴圈之類的後續操作

但是volatile 不是執行緒安全,對其修飾的變數++ 加法減法等操作 保證不了執行緒安全

而AtomicIntegerfieldupdater  實現了普通變數的原子操作 ,加法減都可以

下面給出一個書上的例子,裡面對AtomicIntegerfieldupdater結果進行驗證 驗證藉助了 AtomicInteger,

下面這個例子 說明AtomicIntegerfieldupdater 可以操作物件裡面的屬性,AtomicInteger 只能操作單個的普通變數



下面轉載一個對其理解

對已經new出來的某個變數進行修改,保證其原子性。

AtomicIntegerFieldUpdater使用最重要的在於其建構函式,我們可以在其api檔案中檢視

public static <U> AtomicIntegerFieldUpdater<U>newUpdater(Class<U> tclass,

                                                         String fieldName)

使用方法:

private AtomicIntegerFieldUpdater

<Details>

        atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(

                Details.class"numberTimesInvoked" );

詳細使用程式碼:

  1. import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;  
  2. /** 
  3.  * volatiles cannot be used directly in operations that do x = x + 1 for
     
  4.  * numbers can be skipped or duplicated when there are multiple threads 
  5.  * involved. 
  6.  * <p> 
  7.  * Hardware supports Atomic Compare And Swap operations.  CAS java classes 
  8.  * like AtomicInteger can use this feature of the hardware to ensure that 
  9.  * a "x = x + 1" like operation is atomic. 
  10.  * <p> 
  11.  * However AtomicInteger is significantly more resource intensive than a simple 
  12.  * volatile. If there are many instances of a class which has an AtomicInteger 
  13.  * this increase in resource over a volatile can be significant. 
  14.  * <p> 
  15.  * The AtomicIntegerFieldUpdater comes to the rescue - it can be registered 
  16.  * with a volatile variable of a class and can then be used on multiple 
  17.  * instances of the class. 
  18.  * 
  19.  * If there are 1000s of instances of a class which would ordinarily have 
  20.  * AtomicInteger this can be a big saving. 
  21.  * 
  22.  * AtomicIntegerFieldUpdater is able to update a volatile field of an object 
  23.  * atomically. 
  24.  * 
  25.  * @author John Dickerson 
  26.  */
  27. publicclass AtomicIntegerFieldUpdaterCounter {  
  28.     // AtomicIntegerFieldUpdater is registered with Details.class so that it
  29.     // knows it will later be updating the volatile field called
  30.     // numberTimesInvoked
  31.     //步驟1 構造方法
  32.     private AtomicIntegerFieldUpdater<Details>  
  33.         atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(  
  34.                 Details.class"numberTimesInvoked" );  
  35.     /** 
  36.      * Diferent threads can call this method to update the volatile field of 
  37.      * an instance of Details 
  38.      * 
  39.      * @param details Details object which has the volatile field called 
  40.      * "numberTimesInvoked" in it. 
  41.      * 
  42.      * @return the value of the counter after it has been incremented by one 
  43.      */
  44.     //步驟2 對AtomicIntegerFieldUpdater修飾的變數進行操作
  45.     publicint addOne( Details details ){  
  46.         // performs a "x = x + 1" style atomic operation
  47.         //return atomicIntegerFieldUpdater.addAndGet( details, 1 );
  48.         returnthis.atomicIntegerFieldUpdater.getAndIncrement(details);  
  49.     }  
  50.     publicint subOne(Details details)  
  51.     {  
  52.         return atomicIntegerFieldUpdater.decrementAndGet(details);  
  53.     }  
  54.     /** 
  55.      * See test class for example of using this class with multiple threads, 
  56.      * some of which are writing to the volatile field and some which are 
  57.      * reading from the volatile field 
  58.      * @throws InterruptedException  
  59.      */
  60.     publicstaticvoid main(String[] args) throws InterruptedException {  
  61.      final    AtomicIntegerFieldUpdaterCounter atomicIntegerFieldUpdaterCounter =  
  62.             new AtomicIntegerFieldUpdaterCounter();  
  63.         // This call would ordinarily be made by many other threads
  64.      final   Details d=new Details();  
  65.         System.out.print("物件d的變數numberTimesInvoked累計前:"+d.getNumberTimesInvoked());  
  66.         System.out.println(",A累計前:"+TestAtomic.A);  
  67.         Thread t0=  new Thread(  
  68.             new Runnable(){  
  69.                 @Override
  70.                 publicvoid run() {  
  71.                     for(int j=0;j<100000;j++)  
  72.                     {  
  73.                         atomicIntegerFieldUpdaterCounter.addOne(d);  
  74.                         TestAtomic.A++;  
  75.                     }         
  76.                 }  
  77.         });  
  78.         Thread t1=  new Thread(  
  79.                     new Runnable(){  
  80.                         @Override
  81.                         publicvoid run() {  
  82.                             for(int j=0;j<100000;j++)  
  83.                             {  
  84.                                 TestAtomic.A++;  
  85.                                 atomicIntegerFieldUpdaterCounter.subOne(d);  
  86.                             }         
  87.                         }  
  88.                 });  
  89.         t0.start();  
  90.         t1.start();  
  91.         t0.join();  
  92.         t1.join();  
  93.          System.out.print("物件d的變數numberTimesInvoked累計後:"+d.getNumberTimesInvoked());  
  94.          System.out.println(",A累計後:"+TestAtomic.A);  
  95.     }  
  96. }  
  1. /** 
  2.  * @author John Dickerson 
  3.  */
  4. publicclass Details {  
  5.     volatileint numberTimesInvoked;  
  6.     publicint getNumberTimesInvoked() {  
  7.         return numberTimesInvoked;  
  8.     }  
  9.     publicvoid setNumberTimesInvoked(int numberTimesInvoked) {  
  10.         this.numberTimesInvoked = numberTimesInvoked;  
  11.     }  
  12. }  



執行結果如下:

物件d的變數numberTimesInvoked累計前:0,A累計前:0

物件d的變數numberTimesInvoked累計後:0,A累計後:199947

從上述程式碼中我們可以看出,新建立的:Details d=newDetails();物件d的變數numberTimesInvoked,經過this.atomicIntegerFieldUpdater.getAndIncrement(d); 構造後成了一個執行緒安全的變數。

http://blog.csdn.net/leixingbang1989/article/details/50496201