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());
    }
}
相关推荐
qmx_077 分钟前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
为风而战15 分钟前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
技术无疆2 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
架构文摘JGWZ5 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
拾光师6 小时前
spring获取当前request
java·后端·spring
aPurpleBerry6 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
我是苏苏6 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
xujinwei_gingko6 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring
2301_789985946 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习
IT学长编程6 小时前
计算机毕业设计 教师科研信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·毕业设计·springboot·毕业论文·计算机毕业设计选题·计算机毕业设计开题报告·教师科研管理系统