JAVA通过循环CAS实现原子操作

java可以通过循环CAS的方式实现原子操作。下面介绍循环CAS的方式。

循环CAS实现原子操作

循环CAS的基本思路就是通过循环执行CAS操作,直到执行成功跳出循环。
以下代码实现基于CAS线程安全的计数器方法safeCount()和非线程安全计数器count。
初始化100个线程,每个线程执行1w次计数,线程安全的结果应该是100w,而非线程安全的结果可能会小于这个数。

public class Counter {
    private AtomicInteger atomicI = new AtomicInteger(0);
    private int i = 0;

    public static void main(String[] args) {
        final Counter cas = new Counter();
        List<Thread> threads = new ArrayList<>(600);
        long start = System.currentTimeMillis();

        //初始化100个线程,每个线程执行1w次计数
        for(int j=0; j<100; j++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i=0; i<10000; i++){
                        cas.safeCount();
                        cas.count();

                    }

                }
            });
            threads.add(thread);
        }

        for (Thread thread : threads) {
            thread.start();
        }

        //等待所有线程执行完成
        for(Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //非线程安全的结果:<100w
        System.out.println(cas.i);
        //线程安全的结果: 100w
        System.out.println(cas.atomicI.get());
        System.out.println(System.currentTimeMillis() - start);

    }

    /**
     * 使用CAS实现线程安全计数
     */
    private void safeCount() {
        //自旋CAS,直到成功跳出循环
        for(;;) {
            int i = atomicI.get();
            boolean suc = atomicI.compareAndSet(i, ++i);
            if (suc) {
                break;
            }
        }
    }

    /**
     * 非线程安全计数
     */
    private void count() {
        i++;
    }

}

CAS实现原子操作的问题

循环CAS存在三大问题:ABA问题,循环时间长开销大,只能保证一个共享变量的原子操作。

ABA问题

什么是ABA问题?
如果一个值原来是A,变成了B,又变成了A。那么CAS认为值没有发生变化,实际上是发生了变化的。

解决思路:在变量前面追加版本号
A -> B -> A就会变成1A -> 2B -> 3A

这里是完整的 代码

参考资料:
方腾飞《Java并发编程的艺术》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值