速学!Java 原子操作,开启并发编程新境界

原子操作

在java.util.concurrent.atomic包下提供了很多原子操作类,多个线程执行一个操作时,其中任何一个线程要么完全执行此操作,要么没有执行此操作的任何步骤,其内部使用的Unsafe来实现的CAS操作 乐观锁

以AtomicInteger为例

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

    // setup to use Unsafe.compareAndSwapInt for updates
  // Unsafe实例
    private static final Unsafe unsafe = Unsafe.getUnsafe();
  // 存放value的偏移量
    private static final long valueOffset;

    static {
        try {
          // 获取value的偏移量
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

    // 获取当前值
    public final int get() {
        return value;
    }

    // 设置给定值
    public final void set(int newValue) {
        value = newValue;
    }

    // 延时设置
    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }

    // 以原子方式设置给定值,并返回旧值  线程安全版本的  tmp = oldValue;  oldValue = newValue; return oldValue
    public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }

    // 如果当前值等于预期值,则以原子方式设置为给定的更新值,成功则返回true,失败返回false
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    // 如果当前值等于预期值,则以原子方式设置为给定的更新值,成功则返回true,失败返回false
   // 与compareAndSet方法一样
    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    // 以原子方式加一 ,相当于线程安全版的i++
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

    // 以原子方式减一 ,相当于线程安全版的i--
    public final int getAndDecrement() {
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }

    // 以原子方式将给定值与当前值相加 线程安全版的i=+10  先获取再相加
    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }

   // 以原子方式加一 ,相当于线程安全版的++i
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

     // 以原子方式减一 ,相当于线程安全版的--i
    public final int decrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
    }

    // 以原子方式将给定值与当前值相加 线程安全版的i+=10  先相加在获取
    public final int addAndGet(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
    }

}

指令重排序

JVM会根据处理器的特性适当的重新排序机器指令,使机器指令更符合CPU的执行特点,最大限度的发挥机器的性能,但是会导致执行顺序可能会与代码顺序不一致

参考文献

相关推荐
派大鑫wink18 小时前
【JAVA学习日志】SpringBoot 参数配置:从基础到实战,解锁灵活配置新姿势
java·spring boot·后端
程序员爱钓鱼18 小时前
Node.js 编程实战:文件读写操作
前端·后端·node.js
xUxIAOrUIII18 小时前
【Spring Boot】控制器Controller方法
java·spring boot·后端
Dolphin_Home18 小时前
从理论到实战:图结构在仓库关联业务中的落地(小白→中级,附完整代码)
java·spring boot·后端·spring cloud·database·广度优先·图搜索算法
zfj32118 小时前
go为什么设计成源码依赖,而不是二进制依赖
开发语言·后端·golang
weixin_4624462318 小时前
使用 Go 实现 SSE 流式推送 + 打字机效果(模拟 Coze Chat)
开发语言·后端·golang
JIngJaneIL19 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小信啊啊19 小时前
Go语言切片slice
开发语言·后端·golang
阿里嘎多学长20 小时前
2025-12-16 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Victor35621 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端