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());
    }
}
相关推荐
rannn_11121 分钟前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
IKUN家族2 小时前
Spring IoC&DI
java·spring·rpc
山荷枝3 小时前
03-框架--Spring
java·后端·spring
ChaHae-In4 小时前
SpringBoot统一功能处理
java·spring boot·后端
coder!mq4 小时前
说几个常见的语法糖?
java·开发语言·算法
gugucoding4 小时前
38. 【Java】Stream API(下):高级操作与性能
java·开发语言
心平气和量大福大5 小时前
android-实例-蒲公英-更新与安装-5-签名与生成APK
android·java·开发语言
952365 小时前
Spring-cloud配置中心
java·spring·spring cloud·微服务
ydd1001005 小时前
寻找两个正序数组的中位数 Java 题解,二分分割详解
java·开发语言
真上帝的左手7 小时前
10. 软件设计&架构-Spring Security 7 整合CAS SSO 单点登录
java·spring·架构·sso