36.基于CAS实现的java类

JUC, java.util.concurrent并发工具包下。

1.原子整数

AtomicInteger

AtomicLong

AtomicBoolean

底层用的CAS来实现。

AtomicInteger类的incrementAndGet方法,addAndGet方法

java 复制代码
public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger();
        int i = atomicInteger.incrementAndGet(); //i++
        log.info("i=={}", i);
        //这里返回的是1,但是atomicInteger中的值已经变成2了
        int j = atomicInteger.getAndIncrement();//++i
        log.info("j=={}", j);
        log.info("value=={}", atomicInteger.get());

        //先返回原来的值
        int andAdd = atomicInteger.getAndAdd(2);
        log.info("andAdd={}", andAdd);
        //返回加运算之后的值
        int i1 = atomicInteger.addAndGet(3);
        log.info("i1=={}", i1);

    }
复制代码
int andAdd = atomicInteger.getAndAdd(-1 * 2); //减法

AtomicInteger类的updateAndGet方法的原理分析:

复制代码
public final int updateAndGet(IntUnaryOperator updateFunction) {
    int prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
    } while (!compareAndSet(prev, next));
    return next;
}

IntUnaryOperator这个接口中定义了方法 int applyAsInt(int prev),所以调用者只需要传入applyAsInt方法的实现逻辑即可。

复制代码
AtomicInteger atomicInteger = new AtomicInteger(5);
//**乘法
int i2 = atomicInteger.updateAndGet(e -> e * 10);
log.info("i2=={}", i2);

2.原子引用类型

AtomicReference

AtomicMarkableReference

AtomicStampedReference

java 复制代码
public class AccountDemo {
    public static void main(String[] args) {
        BigdecimalAccountCAS bigdecimalAccountCAS = new BigdecimalAccountCAS(new BigDecimal("10000"));
        BigDecimalAccount.demo(bigdecimalAccountCAS);
    }
}

class BigdecimalAccountCAS implements BigDecimalAccount{

    private AtomicReference<BigDecimal> balance;

    public BigdecimalAccountCAS (BigDecimal balance) {
        this.balance = new AtomicReference<>(balance);
    }

    @Override
    public BigDecimal getBalance() {
        return this.balance.get();
    }

    @Override
    public void withDraw(BigDecimal amont) {
        while(true) {
            BigDecimal prev = balance.get();
            BigDecimal subtract = prev.subtract(amont);
            if (balance.compareAndSet(prev, subtract)) {
                break;
            }
        }
//        this.balance.updateAndGet(e -> e.subtract(amont));
    }
}


interface BigDecimalAccount {

    //获取余额
    BigDecimal getBalance();

    //取款
    void withDraw(BigDecimal amont);

    static void demo(BigDecimalAccount account) {
        //定义一个线程集合
        List<Thread> ts = new ArrayList<>();
        long start = System.nanoTime();
        //创建一千个线程,每个线程取出10元
        for (int i = 0; i < 1000; i++) {
            ts.add(new Thread(() -> account.withDraw(BigDecimal.TEN)));
        }
        //启动每一个线程
        ts.forEach( e -> e.start());
        //等所有线程执行完毕
        ts.forEach( e -> {
            try {
                e.join();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        });
        long duration = System.nanoTime() - start;
        System.out.println("花费时长:"+duration);
        System.out.println("余额:"+ account.getBalance());
    }
}
相关推荐
lang201509282 分钟前
Java JSON绑定API:JSR 367详解
java·java-ee
eWidget9 分钟前
随机森林原理:集成学习思想 —— Java 实现多棵决策树投票机制
java·数据库·随机森林·集成学习·金仓数据库
xqqxqxxq27 分钟前
Java Thread 类核心技术笔记
java·笔记
LGL6030A37 分钟前
Java学习历程26——线程安全
java·开发语言·学习
pcm12356744 分钟前
设计C/S架构的IM通信软件(4)
java·c语言·架构
带刺的坐椅1 小时前
用 10 行 Java8 代码,开发一个自己的 ClaudeCodeCLI?你信吗?
java·ai·llm·agent·solon·mcp·claudecode·skills
Nebula_g1 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
HAPPY酷2 小时前
构造与析构:C++ 中对象的温柔生灭
java·jvm·c++
lang201509282 小时前
Java JSR 250核心注解全解析
java·开发语言
czhc11400756632 小时前
协议 25
java·开发语言·算法