Java 原子类 java.util.concurrent.atomic

本文详细解析了Java原子类及其在并发编程中的应用,特别着重介绍了AtomicInteger的实现细节,包括volatile的作用、compareAndSet方法的原理以及set与lazySet方法的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 原子类 java.util.concurrent.atomic

 

1、i++为什么是非线程安全的

i++其实是分为3个步骤:获取i的值, 把i+1, 把i+1的结果赋给i

如果多线程执行i++操作,没有同步的话,结果可能不正确

如两个线程同时获取i的值,然后各自+1后,赋给i。正确的情况下i的值应该是加了2,但这里其实加了1而且,前面的结果被覆盖了。

通常做法:synchronized (synchronized方法,synchronized变量), 但这样做效率不是最优的。

 

2、AtomicInteger的实现

 主要依靠:1、volatile 保证了变量的可见性,所有线程不缓存volatile变量,需要时都从内存读取,这样能保证所有数据拿到的值都是最新的。

2、compareAndSet(int expect, int update)判断当前值==expect?当前值=update:错误;

这里做了两步操作,判断跟赋值。但因为cpu提供这样指令的支持,所有能保证这个操作时原子的。

 

 

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
      try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;
 

 

 

3、AtomicInteger 中的set(int newValue) lazySet(int newValue)

void set(int newValue)

设置为给定值。 直接修改原始值,也就是i=newValue操作。

 

void lazySet(int newValue) 最后设置为给定值。

延时设置变量值,这个等价于set()方法,但是由于字段是volatile类型的,因此次字段的修改会比普通字段(非volatile字段)有稍微的性能延时(尽管可以忽略),所以如果不是想立即读取设置的新值,允许在“后台”修改值,那么此方法就很有用。如果还是难以理解,这里就类似于启动一个后台线程如执行修改新值的任务,原线程就不等待修改结果立即返回(这种解释其实是不正确的,但是可以这么理解)。

 

  

 


 

 

 

 


 

 

4、AtomicInteger中compareAndSet(int expect, int update)  weakCompareAndSet(int expect, int update)

 

boolean weakCompareAndSet(int expect, int update)
        如果当前值 == 预期值,则以原子方式将该设置为给定的更新值。JSR规范中说:以原子方式读取和有条件地写入变量但 创建任何 happen-before 排序,因此不提供与除weakCompareAndSet 目标外任何变量以前或后续读取或写入操作有关的任何保证。大意就是说调用weakCompareAndSet时并不能保证不存在happen-before的发生(也就是可能存在指令重排序导致此操作失败)。但是从Java源码来看,其实此方法并没有实现JSR规范的要求,最后效果和compareAndSet是等效的,都调用了unsafe.compareAndSwapInt()完成操作。

 

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
	return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
     * and does not provide ordering guarantees, so is only rarely an
     * appropriate alternative to {@code compareAndSet}.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful.
     */
    public final boolean weakCompareAndSet(int expect, int update) {
	return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值