假设现在有这样的一个场景: 一百个线程同时对一个int对象进行修改,要求只能有一个线程可以修改。

看看下面程序是否正确:

    private static int a = 100;
private static volatile boolean ischanged = false;
public static void main(String[] args){
for(int i=0; i<100;i++){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
if(!ischanged){
ischanged = true;
a = 120;
}
}
});
t.start();
}
}

对于volatile变量,写的时候会将线程本地内存的数据刷新到主内存上,读的时候会将主内存的数据加载到本地内存里,所以可以保证可见行和单个读/写操作的原子性。但是上例中先 1. 判断!ischanged 2.ischanged=true  该组合操作就不能保证原子性了,也就是说线程A A1->A2  线程B B1->B2(第一个操作为volatile读或者第二个操作为volatile写的时候,编译器不会对两个语句重排序,所以最后的执行顺序满足顺序一致性模型的),但是最后的执行结果可能是A1->B1->A2->B2。不满足需求

AtomicIntegerFieldUpdater:  基于反射的工具,可用CompareAndSet对volatile int进行原子更新:

修改上个场景的代码,如下:

public class Test{
private static AtomicIntegerFieldUpdater<Test> update = AtomicIntegerFieldUpdater.newUpdater(Test.class, "a");
private static Test test = new Test();
public volatile int a = 100;
public static void main(String[] args){
for(int i=0; i<100;i++){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
if(update.compareAndSet(test, 100, 120)){
System.out.print("已修改");
}
}
});
t.start();
}
}
}
用AtomicIntegerFieldUpdater.newUpdater指定类里面的属性。这里我们要更新Test类里面的A字段(必须是volatile且不是static对象)。update.compareAndSet()方法使用cas机制,每次提交的时候都比较下test.a是不是100,如果是,则更新。

AtomicIntegerFieldUpdater使用的更多相关文章

  1. java多线程系类:JUC原子类:05之AtomicIntegerFieldUpdater原子类

    概要 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法 ...

  2. LongAdder,AtomicIntegerFieldUpdater深入研究

    从LongAdder看更高效的无锁实现 AtomicIntegerFieldUpdater字段原子更新类 div:not([id]){display:none;} --> ul{padding: ...

  3. java并发编程:线程安全管理类--原子操作类--AtomicIntegerFieldUpdater<T>

    1.类 AtomicIntegerFieldUpdater<T> public abstract class AtomicIntegerFieldUpdater<T> exte ...

  4. AtomicIntegerFieldUpdater用法

    一个基于反射的工具类,它能对指定类的指定的volatile字段进行原子更新 下面是netty源码中AbstractReferenceCountedByteBuf类的使用 private static ...

  5. 并发之AtomicIntegerFieldUpdater

    基于反射的实用工具,可以对指定类的指定 volatile int 字段进行原子更新.此类用于原子数据结构,该结构中同一节点的几个字段都独立受原子更新控制. 先来看一段代码: package autom ...

  6. AtomicIntegerFieldUpdater字段原子更新类

    本文链接:https://blog.csdn.net/anLA_/article/details/78662383前面讲的两个AtomicInteger和AtomicIntegerArray,这两个都 ...

  7. AtomicIntegerFieldUpdater和AtomicInteger

    为什么有了AtomicInteger还需要AtomicIntegerFieldUpdater? 当需要进行原子限定的属性所属的类会被创建大量的实例对象, 如果用AtomicInteger, 每个实例里 ...

  8. AtomicIntegerFieldUpdater 源码分析

    AtomicIntegerFieldUpdater AtomicIntegerFieldUpdater 能解决什么问题?什么时候使用 AtomicIntegerFieldUpdater? 1)字段必须 ...

  9. java并发AtomicIntegerFieldUpdater

    java并发AtomicIntegerFieldUpdater 支持对象的成员变量原子操作类由AtomicIntegerFieldUpdater,AtomicLongFieldUpdater, Ato ...

随机推荐

  1. H5新增API和操作DOM

    博客原文:https://dobinspark.com.cn/ H5-dom扩展 获取元素 document.getElementsByClassName ('class'); //通过类名获取元素, ...

  2. django-模板层基础2

    1.模板的导入 {% include 模板名%} 首先在你的的项目中,需要很多地方用到同一个组件(相对于头部,你进行每个页面的切换,网页最上面的头 部不需要改变),那么这样我们可以把那个头部重新写在一 ...

  3. react中图片校验码实现以及new Buffer()使用方法

    图片校验码原理就是图片是后端生成的前端只是前后端传过来的数据流做些处理展示即可,先直接上核心代码图: 这里就是简单得对axios的一些默认项属性重写:最后你只需要将resolve的内容插入页面的< ...

  4. SpringBoot配置redis和分布式session-redis

    springboot项目 和传统项目 配置redis的区别,更加简单方便,在分布式系统中,解决sesssion共享问题,可以用spring session redis. 1.pom.xml <d ...

  5. 发送post请求几种常见content-type类型

    application/x-www-form-urlencoded 这应该是最常见的 POST 提交数据的方式了.浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 app ...

  6. hadoop生态搭建(3节点)-04.hadoop配置

    如果之前没有安装jdk和zookeeper,安装了的请直接跳过 # https://www.oracle.com/technetwork/java/javase/downloads/java-arch ...

  7. 软件的按契约设计(DbC---Design by Contract)

    一.DbC基本概念 DbC的思想源于商业活动中商家和用户的行为(义务和利益关系),双方都要遵守一个契约(合同),交易才能完成. 商家与用户的契约关系如下: 1. 商家必须提供某种产品(义务),并有权获 ...

  8. 初识python 面向对象

    what the f**k!!这个知识点学不好的最大元凶就是,我还单身??? python基础(四): 面向对象的三个特点: 封装,继承,多态 类: 对象是面向对象编程的核心,在使用对象的过程中,为了 ...

  9. 常用数字信号的产生(C实现)-ARMA模型数据生成

    ARMA模型属于信号现代谱估计的范畴,AR模型常用于信号的线性预测.AR模型最后归结为线性方程,MA最后为非线性方程,因此,AR模型使用较多. AR模型最后归结为解Yule-Walker方程,对应矩阵 ...

  10. Java——自动生成30道四则运算---18.09.27

    package chuti;import java.io.PrintWriter;import java.util.Scanner;import java.io.FileNotFoundExcepti ...