Java AtomicReference 中 compareAndSet的更新问题
private static AtomicReference<Integer> atomicReference = new AtomicReference<>(0);

    private static AtomicReference<Integer> atomicReference1 = new AtomicReference<>(100);

 atomicReference.compareAndSet(0, 2);
        atomicReference.compareAndSet(0, 3);
        atomicReference.compareAndSet(2, 4);
        atomicReference.compareAndSet(3, 5);
        System.out.println(atomicReference.get());


        atomicReference1.compareAndSet(100, 200);
        atomicReference1.compareAndSet(100, 300);
        atomicReference1.compareAndSet(200, 400);
        atomicReference1.compareAndSet(300, 500);
        System.out.println(atomicReference1.get());

然而运行出来的结果
atomicReference为4
atomicReference1为200.

问题.atomicReference1为什么是200 而不是400

0

2个回答

首先compareAndSet使用==比较,看注释:
Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.

    其次为什么128以内的整数可以而超过128不可以?
    对于int字面量java会进行装箱将其转换成Integer对象,调用的是Integer.valueOf方法,
    看源码你就明白了,128以内的会使用缓存,同一个int字面量返回同一个对象用==比较为true,而超过128返回不是同一个对象,==为false,equal才是true:
    public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}
    祝你好运!
2
u012470804
飞翔的小野鸭 非常感谢你的回答
大约一年之前 回复

这个问题眼前一亮,好问题。我们一般会使用AtomicReference的CAS保证原子性,但是它是通过比较引用是否相同判断是否可以更新。

 atomicReference1.compareAndSet(100, 200);
 atomicReference1.compareAndSet(100, 300);
 atomicReference1.compareAndSet(200, 400);
 atomicReference1.compareAndSet(300, 500);
 System.out.println(atomicReference1.get());

初始值为常量池中的100,第一步中100会先转成Integer.valueOf(100),这个对象其实就是常量池中的100,第一步相同可以更新为200。
再向后面Integer.valueOf(200) != Integer.valueOf(200),所以以后都不等,最终结果为200.

0
u012470804
飞翔的小野鸭 谢谢你的回答. 但是上面那个答案回答得比较通俗易懂. 所以就采纳他的了.
大约一年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Java并发学习(九)-AtomicIntegerFieldUpdater字段原子更新类
前面讲的两个AtomicInteger和AtomicIntegerArray,这两个都是在最初设计编码时候就已经考虑到了需要保证原子性。但是往往有很多情况就是,由于需求的更改,原子性需要在后面加入,类似于我不要求你这整个类操作具有原子性,我只要求你里面一个字段操作具有原子性。没错,concurrent.atomic包下AtomicIntegerFieldUpdater就是这个作用的。AtomicXX
并发实战——原子类AtomicReference及底层源码CompareAndSwapObject分析
本文内容: 分析原子类AtomicReference 分析源码 AtomicReference中public final boolean compareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); }public final
Java多线程之进阶篇(二)
接下来,我们继续学习Java多线程之进阶篇。Java多线程之进阶篇(一)介绍了线程池的相关内容,让我们大致对线程池有了初步的整体的认识,但是具体到稍微深入的知识点还是有点懵,这一篇主要介绍JUC的原子类。 在Java SE5 中java.util.concurrent.atomic包下提供了一系列支持无锁线程安全修改操作的基础变量。这些原子类是对volatile机制的扩展,并提供下面形式的原子性...
java Atomic原子更新
在jdk&amp;gt;=1.5提供了atomic原子数据类,其目的就是方便多线程,无锁简单地进行原子操作   大概分为4类:     变量类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicRefrence     数组类:AtomicIntergerArray,AtomicLongArray,AtomicRefreceArray    更新器类:...
并发学习-【转】深入理解并发之CompareAndSet(CAS)
程老师原文地址:http://flychao88.iteye.com/blog/2269438原文如下:一、CAS简介CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁,使用这些类在多核CPU的机器上会有比较好的性能. CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B
【Java并发编程】AtomicReference 原子引用
概述: AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,底层采用的是compareAndSwapInt实现CAS,比较的是数值是否相等,而AtomicReference则对应普通的对象引用,底层使用的是compareAndSwapObject实现CAS,比较的是两个对象的地址是否相等。也就是它可以保证你在修改对象引用时的...
Java并发24:Atomic系列-原子类型数组AtomicXxxxArray学习笔记
[超级链接:Java并发学习系列-绪论] [系列概述: Java并发22:Atomic系列-原子类型整体概述与类别划分] 本章主要对原子类型数组进行学习。 1.原子类型数组 在java.util.concurrent.atomic中,原子类型数组有以下三种: AtomicLongArray:提供对int[]数组元素的原子性更新操作。 AtomicIntegerArray:提供对...
史上最简单易懂的 AtomicReference 源码解析和使用
1、作用: 1、概述:是对 ”对象” 进行原子操作,用于描述的原子包规范原子变量的性质 提供了一种读和写都是原子性的对象引用变量。 原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。 2、 AtomicReference 和 AtomicInteger 非常类似,不同之处就在于 AtomicIn...
AtomicReference源码解析和使用
AtomicReference是作用是对"对象"进行原子操作。 提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态
JAVA多线程并行计算乐观锁之Atomic系列详解
从多线程并行计算乐观锁 和 悲观锁 来讲,JAVA中的 lock、synchronized 属于悲观锁,即是在操作某数据的时候总是会认为多线程之间会相互干扰,属于阻塞式的加锁;Atomic系列则属于乐观锁系列,即当操作某一段数据的时候,线程之间是不会相互影响,采用非阻塞的模式,直到更新数据的时候才会进行版本的判断是否值已经进行了修改。 Atomic在JAVA中的家族如下: a、基本类:Atom...
如何解决AtomicInteger的ABA的问题
AtomicInteger 与 ABA 问题。 java.util.concurrent.atomic 包下 AtomicBoolean、 AtomicInteger 、AtomicLong 等以 Atomic* 开头的类原理是一致的,都采用基于 CAS 的乐观锁实现。 CAS 对于一个要更新的变量 V,我们提供一个它的旧值 A 和新值 B,如果变量 V 的值等于旧值 A,那么更新成功,否则更...
compareAndSet 最牛逼的解释
Java BigDecimal详解_动力节点Java学院整理
借用《Effactive Java》这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,例如银行存款数额,这时候BigDecimal就派上大用场啦。
atomic类与hashmap的组合
针对多线程位点提交问题 import java.util.HashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; /** * 测试hashmap 与 Atomic类的组合 * 在获取hashmap的key entry时不加锁 (ha
日常小结-在内部类中必须使用Atomic原子类替换volatile类
最近在看《java并发编程实战》的时候,发现了一些缺乏的知识点,这里做一下整理。这里强力推荐下这本书。向匿名内部类传递的参数必须是final类型的在第七章取消与关闭的时候,看到了程序清单7-20的时候有个注解 之所以采用AtomicBoolean来代替volatile类型的boolean,是因为能从内部的Runnable中访问hasNewMail标志,因此它必须是final类型以免修改。 之前在
高并发编程之AtomicReference讲解
一、AtomicReference介绍 ①.AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用。也就是它可以保证你在修改对象引用时的线程安全性。 ②.AtomicReference是作用是对”对象”进行原子操作。 提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程...
AtomicReference源码解析及应用与应用拓展
AtomicReference赋值操作是非线程安全的,一般会在数据库中用锁来实现变更赋值,如果不用锁,可以用AtomicReference&lt;V&gt;类,实现将对象进行原子操作。提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。 一、源码解析 pub...
AtomicBoolean介绍与使用
AtomicBoolean是java.util.concurrent.atomic包下的原子变量,这个包里面提供了一组原子类。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入,这只是一种逻辑上的理解。实际
java中的原子操作类AtomicInteger及其实现原理
/**          * 一,AtomicInteger 是如何实现原子操作的呢?          *          * 我们先来看一下getAndIncrement的源代码:          *    public final int getAndIncrement() {          *        for (;;) {          *
Java concurrency之AtomicReference原子类_动力节点Java学院整理
Java concurrency之AtomicReference原子类_动力节点Java学院整理,动力节点口口相传的Java黄埔军校
【实战Java高并发程序设计 3】带有时间戳的对象引用:AtomicStampedReference
AtomicReference无法解决上述问题的根本是因为对象在修改过程中,丢失了状态信息。
Java-原子操作和原子变量
API链接:https://docs.oracle.com/javase/8/docs/api/所在包:java.util.concurrent.atomic Java有8种数据类型,并且每个数据类型都有一个包装类,如int和Integer,它们之间的转化也就是我们常称作的自动拆箱和装箱的过程。但是呢,它们只是一个简单的数据,当在并发编程下,没有任何特殊的语义。volatile能保证可见性,以及阻...
JAVA SE 8 学习笔记(五)并发增强
1.原子值 java5开始,提供了一些原子操作的类,如AtomicInteger、AtomicLong等 这些类提供了诸如incrementAndGet这样的原子操作方法。 单数如果想进行复杂操作,则需要使用compareAndSet进行循环处理 do { // .. 计算 } while (!atomicLong.compareAndSet(old, new));
笑谈java并发编程一之AtomicBoolean介绍
Java的java.util.concurrent.atomic这个包下提供了很多的原子性操作的api,可供在多线程中保证操作的原子性,不会发生线程不安全的操作 实现某个时间段只能有一个工作人员进行工作的实例,线程不安全代码如下: public class BarWorker implements Runnable { //设置某段时间内只能有一个工作人员进行工作,其他的只能放弃工作的机会
Java原子类
概述 原子类由CAS操作保证原子性,由volatile关键字保证可见性。 原子类自jdk 1.5开始出现,位于j.u.c.atomic包下面,包含12个类,jdk 1.8又新增了4个性能更好的原子类。 可以粗略分成五类: 1.整型、长整型、布尔型、引用类型的原子类 AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference 2.整型数组
协程源码中的原子操作为什么使用 AtomicReferenceFieldUpdater?
概要AtomicReferenceFieldUpdater 比 AtomicReference 用起来稍微有些麻烦,可大佬为什么更喜欢它?正文SafeContinuati...
java8实战:Lambda 表达式
Java 8 Lambda 表达式 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。 Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。 lambda表达式是一段可以传递的代码,它的核心思想是将面向对象中的传递数据变成传递行为。 语法 lambda 表达式的语法格式如下:
Golang同步:原子操作使用
原子操作即是进行过程中不能被中断的操作。针对某个值的原子操作在被进行的过程中,CPU绝不会再去进行其他的针对该值的操作。 为了实现这样的严谨性,原子操作仅会由一个独立的CPU指令代表和完成。GO语言提供的原子操作都是非入侵式的,由标准库sync/atomic中的众多函数代表 类型包括int32,int64,uint32,uint64,uintptr,unsafe.Pointer,共六个。 这些
【JDK源码】java.util.concurrent.atomic包常用类详解
&amp;nbsp;&amp;nbsp;java.util.concurrent.atomic原子操作类包里面提供了一组原子变量类。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入,这只是一种逻辑上的理解。实际上是借...
高并发编程之AtomicReferenceArray讲解
一、AtomicReferenceArray介绍 AtomicReferenceArray类提供了可以原子读取和写入的底层引用数组的操作,并且还包含高级原子操作。 AtomicReferenceArray支持对底层引用数组变量的原子操作。 它具有获取和设置方法,如在变量上的读取和写入。 也就是说,一个集合与同一变量上的任何后续获取相关联。 二、AtomicReferenceArray几个常用的方法...
Java原子变量与ABA问题(转发)
原文地址:http://www.xiaoyaochong.net/wordpress/?p=201 | 逍遥冲   ABA问题是一种异常现象:如果在算法中的节点可以被循环使用,那么在使用“比较并交换”指令时就可能出现这个问题(如果在没有垃圾回收机制的环境 中)。在CAS操作中将判断“V的值是否仍然为A?”,并且如果是的话就继续执行更新操作。在大多数情况下,这种判断是足够的。然而,有时候还需要...
线程安全性(一) 原子性 AtomicReference
AtomicReference示例 对指定类的指定int字段的原子性更新; 被操作的字段必须用votatile修饰; import com.example.concurrency.annotations.ThreadSafe; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import...
Netty中关于引用计数的retain()/release()方法原子特性的关键compareAndSet
我们知道,实现了ReferenceCounted接口的类的对象都会在引用计数的作用下进行显式的回收。当引用计数为0时,这个对象就不能再被访问了。而这个接口提供了两个方法给我们来操作引用计数。 retain()release()而这个操作是必须保证是在多线程的情况下是安全的,所以他们的操作都是原子的。以retain为例 private ReferenceCounted retain0(int ...
源码看JAVA【三十一】AtomicReference
说明:AtomicReferenc&amp;lt;V&amp;gt;:泛型原子操作,提供了原子操作的设置值操作,并没有自增自减等具有数值特性的方法,相对来说较为简单。仅提供了原子操作的通用方法。针对AtomicInteger为何不继承AtomicReference,因为底层针对特定的类型具有更高的性能。 1、声明与定义 private static final Unsafe unsafe = Uns...
浅析atomic原子性
什么是atomic java.util.concurrent.atomic包中的很多类使用很高效的机器级指令(而不是锁)来保证操作的原子性。 有哪些常用的类 查看api可以知道atomic包下含有以下 比较常用的有AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong等。 看看怎么使用 以AtomicLong举例,得到
多线程 - 原子变量AtomicReference
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; /** * 原子变量 atomicReference用法 * * @author ZHE
使用atomic多线程的原子操作
(本段日志摘抄自:http://cw550284.iteye.com) java.util.concurrent.atomic AtomicBoolean 可以用原子方式更新的 boolean 值。 AtomicInteger 可以用原子方式更新的 int 值。 AtomicIntegerArray 可以用原子方式更新其元素的 int 数组。 AtomicIntegerFiel...
AtomicReference msg
![图片说明](https://img-ask.csdn.net/upload/201803/08/1520503117_163744.png)n这里的原子有什么作用啊,用来显示消息,那为啥不能直接string类型。 AtomicReference的用法和作用是啥?
单机任务重试机制——重启不丢任务
任务失败重试机制某些场景下业务失败需要重试,比如说状态通知第三方,发奖品,发短信等等。总体的思路是将任任务现场记录下来,然后稍后重试。方案有多种 任务现场存储在db中,使用分布式任务调度统一去执行。 任务现场存储在文件中, 各自重试。 方案二的依赖少,而且能做到各个机器的隔离,但是没有HA。方案一具有HA,但实现与机器相关的业务场景比较难,比如某台机器缓存更新失败,需要稍后重试,而且引入的依赖会很多
javaEE高并发之如何更新库存问题
                      javaEE高并发之如何更新库存问题     有三个阶段可更新库存:成功加入购物车;点击去支付,生成订订单;点击支付。 分析: 1、加入购物车并不代表用户一定会购买,如果这个时候开始预占库存,会导致想购买的无法加入购物车。而不想购买的人一直占用库存,这样的情况对商家是不利的,显然这种做法是不可取的。 2、商品加入购物车后,选择下单,这个时候去预占...