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" );
详细使用代码:
- import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
- /**
- * volatiles cannot be used directly in operations that do x = x + 1 for
- * numbers can be skipped or duplicated when there are multiple threads
- * involved.
- * <p>
- * Hardware supports Atomic Compare And Swap operations. CAS java classes
- * like AtomicInteger can use this feature of the hardware to ensure that
- * a "x = x + 1" like operation is atomic.
- * <p>
- * However AtomicInteger is significantly more resource intensive than a simple
- * volatile. If there are many instances of a class which has an AtomicInteger
- * this increase in resource over a volatile can be significant.
- * <p>
- * The AtomicIntegerFieldUpdater comes to the rescue - it can be registered
- * with a volatile variable of a class and can then be used on multiple
- * instances of the class.
- *
- * If there are 1000s of instances of a class which would ordinarily have
- * AtomicInteger this can be a big saving.
- *
- * AtomicIntegerFieldUpdater is able to update a volatile field of an object
- * atomically.
- *
- * @author John Dickerson
- */
- public class AtomicIntegerFieldUpdaterCounter {
- // AtomicIntegerFieldUpdater is registered with Details.class so that it
- // knows it will later be updating the volatile field called
- // numberTimesInvoked
- //步骤1 构造方法
- private AtomicIntegerFieldUpdater<Details>
- atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(
- Details.class, "numberTimesInvoked" );
- /**
- * Diferent threads can call this method to update the volatile field of
- * an instance of Details
- *
- * @param details Details object which has the volatile field called
- * "numberTimesInvoked" in it.
- *
- * @return the value of the counter after it has been incremented by one
- */
- //步骤2 对AtomicIntegerFieldUpdater修饰的变量进行操作
- public int addOne( Details details ){
- // performs a "x = x + 1" style atomic operation
- //return atomicIntegerFieldUpdater.addAndGet( details, 1 );
- return this.atomicIntegerFieldUpdater.getAndIncrement(details);
- }
- public int subOne(Details details)
- {
- return atomicIntegerFieldUpdater.decrementAndGet(details);
- }
- /**
- * See test class for example of using this class with multiple threads,
- * some of which are writing to the volatile field and some which are
- * reading from the volatile field
- * @throws InterruptedException
- */
- public static void main(String[] args) throws InterruptedException {
- final AtomicIntegerFieldUpdaterCounter atomicIntegerFieldUpdaterCounter =
- new AtomicIntegerFieldUpdaterCounter();
- // This call would ordinarily be made by many other threads
- final Details d=new Details();
- System.out.print("对象d的变量numberTimesInvoked累计前:"+d.getNumberTimesInvoked());
- System.out.println(",A累计前:"+TestAtomic.A);
- Thread t0= new Thread(
- new Runnable(){
- @Override
- public void run() {
- for(int j=0;j<100000;j++)
- {
- atomicIntegerFieldUpdaterCounter.addOne(d);
- TestAtomic.A++;
- }
- }
- });
- Thread t1= new Thread(
- new Runnable(){
- @Override
- public void run() {
- for(int j=0;j<100000;j++)
- {
- TestAtomic.A++;
- atomicIntegerFieldUpdaterCounter.subOne(d);
- }
- }
- });
- t0.start();
- t1.start();
- t0.join();
- t1.join();
- System.out.print("对象d的变量numberTimesInvoked累计后:"+d.getNumberTimesInvoked());
- System.out.println(",A累计后:"+TestAtomic.A);
- }
- }
- /**
- * @author John Dickerson
- */
- public class Details {
- volatile int numberTimesInvoked;
- public int getNumberTimesInvoked() {
- return numberTimesInvoked;
- }
- public void setNumberTimesInvoked(int numberTimesInvoked) {
- this.numberTimesInvoked = numberTimesInvoked;
- }
- }
运行结果如下:
对象d的变量numberTimesInvoked累计前:0,A累计前:0
对象d的变量numberTimesInvoked累计后:0,A累计后:199947
从上述代码中我们可以看出,新创建的:Details d=newDetails();对象d的变量numberTimesInvoked,经过this.atomicIntegerFieldUpdater.getAndIncrement(d); 构造后成了一个线程安全的变量。