volatile与AtomicIntegerfieldupdater 区别与关系

来源:互联网 发布:手板编程招聘 编辑:程序博客网 时间:2024/06/07 17:27


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" );

详细使用代码:

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


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * @author John Dickerson 
  3.  */  
  4. public class Details {  
  5.   
  6.     volatile int numberTimesInvoked;  
  7.   
  8.     public int getNumberTimesInvoked() {  
  9.   
  10.         return numberTimesInvoked;  
  11.     }  
  12.   
  13.     public void setNumberTimesInvoked(int numberTimesInvoked) {  
  14.   
  15.         this.numberTimesInvoked = numberTimesInvoked;  
  16.     }  
  17. }  



运行结果如下:

对象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
0 0
原创粉丝点击