Java并发编程札记-(三)JUC原子类-05原子方式更新类的指定volatile字段
2017-12-07 20:29
375 查看
AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater和AtomicLongFieldUpdater是基于反射的实用工具,可以提供对关联字段类型的访问。例如AtomicLongFieldUpdater可以对指定类的指定volatile long字段进行原子更新。本文以AtomicLongFieldUpdater为例来学习。
Counter是一个计数器类。
在多线程环境下测试其是否可用。
测试程序,在连续运行100次++counter后,判断计数器值是否为100,如果为100就打印计数器值最终值为100,否则就什么都不打印。
数次运行程序后,发现大多数结果是什么都没有打印,说明次计数器在多线程环境下不可用。
修改计数器类。
在多线程环境下测试其是否可用。数次运行程序后,发现结果全部为计数器值最终值为100。
AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater与AtomicLongFieldUpdater很相似,就不多做介绍了。
本文就讲到这里,想了解Java并发编程更多内容请参考:
Java并发编程札记-目录
END.
API
//构造方法摘要 protected AtomicLongFieldUpdater() //受保护的无操作构造方法,供子类使用。 //方法摘要 long addAndGet(T obj, long delta) //以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。 abstract boolean compareAndSet(T obj, long expect, long update) //如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。 long decrementAndGet(T obj) //以原子方式将此更新器管理的给定对象字段当前值减 1。 abstract long get(T obj) //获取此更新器管理的在给定对象的字段中保持的当前值。 long getAndAdd(T obj, long delta) //以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。 long getAndDecrement(T obj) //以原子方式将此更新器管理的给定对象字段当前值减 1。 long getAndIncrement(T obj) //以原子方式将此更新器管理的给定对象字段的当前值加 1。 long getAndSet(T obj, long newValue) //将此更新器管理的给定对象的字段以原子方式设置为给定值,并返回旧值。 long incrementAndGet(T obj) //以原子方式将此更新器管理的给定对象字段当前值加 1。 abstract void lazySet(T obj, long newValue) //最后将此更新器管理的给定对象的字段设置为给定更新值。 static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) //为对象创建并返回一个具有给定字段的更新器。 abstract void set(T obj, long newValue) //将此更新器管理的给定对象的字段设置为给定更新值。 abstract boolean weakCompareAndSet(T obj, long expect, long update) //如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。 //以下是JDK1.8新增的部分 long getAndUpdate(int i, LongUnaryOperator updateFunction) //将当前值以原子方式更新为updateFunction方法的结果,并返回更新前的值 long updateAndGet(int i, LongUnaryOperator updateFunction) //将当前值以原子方式更新为updateFunction方法的结果,并返回更新后的值 long getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction) //将当前值以原子方式更新为updateFunction方法的结果(方法参数为x和当前值),并返回更新前的值 long accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction) //将当前值以原子方式更新为updateFunction方法的结果(方法参数为x和当前值),并返回更新后的值
例1:AtomicLongFieldUpdater原子方式更新类的指定volatile字段
:通常情况下,在Java中的++i或者-–i不是线程安全的。一般情况下,只能加锁才能保证上述操作的原子性。有了AtomicLongFieldUpdater后,使用AtomicLongFieldUpdater就可以保证上述操作的原子性。Counter是一个计数器类。
class Counter extends Thread { private static long counter = 0; public static long addOne() { return ++counter; } }
在多线程环境下测试其是否可用。
public class CounterTest { public static void main(String[] args) { for (int i = 0; i < 100; i++) { Thread thread = new Thread() { public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if (Counter.addOne() == 100) { System.out.println("计数器值最终值为100"); } } }; thread.start(); } } }
测试程序,在连续运行100次++counter后,判断计数器值是否为100,如果为100就打印计数器值最终值为100,否则就什么都不打印。
数次运行程序后,发现大多数结果是什么都没有打印,说明次计数器在多线程环境下不可用。
修改计数器类。
class Counter { private volatile long counter = 0; static AtomicLongFieldUpdater updater = AtomicLongFieldUpdater.newUpdater(Counter.class, "counter"); static Counter safeCounter = new Counter (); public static long addOne() { return updater.addAndGet(safeCounter, 1); } }
在多线程环境下测试其是否可用。数次运行程序后,发现结果全部为计数器值最终值为100。
实现原理
与其他原子类一样,AtomicLongFieldUpdater也是基于CAS实现的。AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater与AtomicLongFieldUpdater很相似,就不多做介绍了。
本文就讲到这里,想了解Java并发编程更多内容请参考:
Java并发编程札记-目录
END.
相关文章推荐
- Java并发编程札记-(三)JUC原子类-04原子方式更新引用
- solr原子更新-即指定更新某个字段的值
- solr原子更新-即指定更新某个字段的值
- Java并发编程札记-(三)JUC原子类-02原子方式更新单个变量
- SQL如何更新一个字段中指定的值。
- mysql指定将某个字段更新到另一个表中
- Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类
- Dynamics CRM 通过Odata创建及更新记录各类型字段的赋值方式
- centos7 通过rpm方式更新到指定内核版本
- EF更新指定字段...
- Solr局部或指定字段更新之set用法
- 只更新指定字段
- Dynamics CRM 通过Odata创建及更新记录各类型字段的赋值方式
- 二叉树的层次,中序非递归遍历,以递归前序的方式构造二叉树,将二叉树中的e更新为d,输出从根结点出发 到指定结点,依次经过的祖先(即路径),由前序和中序还原二叉树
- Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类
- Hibernate update 仅更新部分字段的实现方式
- entity framework 5 更新指定字段
- Dynamics CRM 通过Odata创建及更新记录各类型字段的赋值方式
- java list对元素进行指定多个字段属性按多种排序方式进行排序
- Java并发25:Atomic系列-原子类型字段更新器AtomicXxxxFieldUpdater学习笔记