java并发(三):atomic和LongAdder

1.AtomicInteger原子类

改写上一节我们使用的代码(上一节:https://blog.csdn.net/qq_35688140/article/details/100629270

此时我们将上一节的int变成了AtomicInteger:

@ThreadSafe
public class CountExample2 {

    // 请求总数
    public static int clientTotal = 5000;

    // 同时并发执行的线程数
    public static int threadTotal = 200;

    public static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore = new Semaphore(threadTotal);// 使用信号量控制并发数
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);//保证所有线程执行完成后执行某操作
        for (int i = 0; i < clientTotal ; i++) {
            executorService.execute(()->{
                try{
                    semaphore.acquire();//获取信号量
                    add();
                    semaphore.release();//释放信号量
                }catch (Exception e){
                    log.info("exception",e);
                }
                countDownLatch.countDown();//每次执行一个循环,计算器减少一次
            });
        }
        countDownLatch.await();//等待计数器变为0
        executorService.shutdown();//关闭线程池
        log.info("count:"+count);
    }

    // count++方法
    public static void add(){
        count.incrementAndGet();
    }
}

运行效果:多次运行都是5000,表明这是一个线程安全类
在这里插入图片描述

核心方法:while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4))有一个自旋锁,不断的比较var2与var5的值,一旦相等就将v1更新成var5+var4

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}

2.LongAdder

LongAdder会将整个数据分离成一个数组,提高数据的计算效率和并行度。而且对于热点数据会分散为多个cell,所有cell累加求和等到最终结果。相当于将单点的更新压力分散到多个点上。在低并发时,通过对base的直接更新来提高性能。

并发低:直接使用atomic效率更高。
并发高:使用LongAdder高率高,但是并发时可能导致数据有误差。

@ThreadSafe
public class AtomicExample3 {

    // 请求总数
    public static int clientTotal = 5000;

    // 同时并发执行的线程数
    public static int threadTotal = 200;

    public static LongAdder count = new LongAdder();//默认初始值为0

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore = new Semaphore(threadTotal);// 使用信号量控制并发数
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);//保证所有线程执行完成后执行某操作
        for (int i = 0; i < clientTotal ; i++) {
            executorService.execute(()->{
                try{
                    semaphore.acquire();//获取信号量
                    add();
                    semaphore.release();//释放信号量
                }catch (Exception e){
                    log.info("exception",e);
                }
                countDownLatch.countDown();//每次执行一个循环,计算器减少一次
            });
        }
        countDownLatch.await();//等待计数器变为0
        executorService.shutdown();//关闭线程池
        log.info("count:"+count);
    }

    // count++方法
    public static void add(){
        count.increment();
    }
}

结果:
在这里插入图片描述

3.AtomicBoolean

通过AtomicBoolean 可以在并发条件下,让某个过程只执行一次。

public class AtomicExample6 {

   private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    // 请求总数
    public static int clientTotal = 5000;

    // 同时并发执行的线程数
    public static int threadTotal = 200;

    public static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newCachedThreadPool();
            final Semaphore semaphore = new Semaphore(threadTotal);// 使用信号量控制并发数
            final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);//保证所有线程执行完成后执行某操作
            for (int i = 0; i < clientTotal ; i++) {
                executorService.execute(()->{
                    try{
                        semaphore.acquire();//获取信号量
                        test();
                        semaphore.release();//释放信号量
                    }catch (Exception e){
                        log.info("exception",e);
                    }
                    countDownLatch.countDown();//每次执行一个循环,计算器减少一次
                });
            }
            countDownLatch.await();//等待计数器变为0
            executorService.shutdown();//关闭线程池
            log.info("ishappened:"+atomicBoolean.get());
    }
    // count++方法
    public static void test(){
        if(atomicBoolean.compareAndSet(false,true)){
            log.info("execute");
        }
    }

}

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值