Java并发编程之CAS算法

在多线程环境下,我们要实现对一个变量自增的话,往往会使用java.util.concurrent.atomic包下的相关实现类。 如下:

public class TestAtomic {
    public static void main(String[] args) {
        ThreadDemo td=new ThreadDemo();
        //开启二十个线程完成自加操作
        for(int x=1;x<=20;x++){
            new Thread(td).start();
        }
    }
}


class ThreadDemo implements Runnable {
    //定义一个AtomicInteger的初始值为0的变量atoInt
    private AtomicInteger atoInt=new AtomicInteger(0);
    @Override
    public void run() {
        try {
            //休眠一下,提高并发性
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(getNum());
    }

    public int getNum() {
        //每次返回的为当前值的下一个值
        return atoInt.incrementAndGet();
    }
}

这里用到原子并发包装类
1:对于变量,原子性操作都用到了volatile关键字,确保线程之间的可见性。
2:用到了CAS(Compare and Swap)算法


CAS算法
这里用到的主要有三个值
主存值 V :从主存中取出值
预估值 A :对于非原子性的操作,再进行下一次计算操作之前,会再次读取主存中的值
更新值 B :根据具体的逻辑,有待跟新的值
这里有关主存的问题,可以参考 这篇文章,在CAS算法中,如果 V==A 则把B的值复制给V,否则什么也不做,并进行下一次尝试。

     *  比如 对于
     *  int num=0;
     *  i=num++;这个操作
     *  在进行num++这个操作的时候,先从主存中获取num的值,然后再进++操作
     *  很明显这是两个步骤,在获取num的值之后,另一个线程可能已经更改了num的值,这时候加的时候明显有问题
     *  CAS算法如下:
     *  获取主存值 V=0
     *  执行之后,在查看一个主存的值 此时如果还是 A=0(没有线程修改)
     *  根据num++的操作,此时B应该更新到值为0+1=1
     *  V=0
     *  A=0
     *  B=1
     *  因为V==A 此时把B的值刷新到主存中V=1;
     *  ************************************************
     *  如果在一个线程读取之后,另一个线程修改了值,即A=1
     *  V=0          
     *  A=1         
     *  B=1         
     *  V!=A,则不会把B的值刷新到主存中
     */

Java并发之CountDownLatch

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值