CAS初略(1)

首先看一段程序:

程序解读:1.我们创建了一个AutomicTest类里面有一个public的将value++的方法。

                   2.我们在main主线程里面新建了两个线程来各做一千次循环。

程序结果预测:两个线程,每个线程做1000次value的自增,我们是不是可以设想答案就是2000呢?

那答案到底是什么呢?我们运行下看看:

运行的结果出乎我们的意料,很大程度的少于2000,那这是怎么回事呢?

我们先看下这个图,大家都可以明白,我们主程序里面的vaule是存储在主内存中,当我们启动两个线程去对value自增的时候,可以想象下我们是开辟了两个工作内存,将主内存的值读取出来写入我们的每个线程自己的工作内存,每次运行的每个线程都从自己的工作内存中读取数据,在当前线程进行自增在写入主内存中,就可以出现写覆盖问题。那我们是不是想到了一个关键字volatile,可以让我们实时读取到工作内存的数据都是最新的,那么是不是就不会出现这样的写覆盖的问题呢?

来,我们尝试下,揭开看下谜底:

我们可以看到我们在变量value前面加了volatile,但是好像不起任何作用,出现的结果还是没有达到我们需要的结果,那到底是怎么回事呢?

我们看下value++是怎么加的,这里可以分为三步:1。首先读取value的值2.value的值做++3.将value++的值在复制给到value这三步,这三步我个人觉得可以细化成每一个小的步骤,如果现在线程1执行了1和2两步,将value自增为1了,这时候线程2也进行了相应额操作,不过线程2比较强悍,直接把三步执行完毕了,将自己的最新的值写会了主内存,这时候线程1继续走,也会把值写入主内存,就又出现了我们所说的写覆盖了,所以这时候的结果还不是我们需要的2000,那我们应该怎么做,才能得到我们需要的结果呢?这里我们也明白了volatile这个关键字为什么不能阻止写覆盖呢?其实volatile这个关键字,只是保证了可见性,但是没有保证原子性,那什么又是原子性呢?

原子性:简单点说就是一系列的操作,要不都完成了,要不都不完成,即使某个任务已经完成了99%,但是最后的1%没有都是不可以的。

那我们是不是可以将这个程序改下呢?

首先我们先来认识一个名词:CAS(Compare and Swap)比较并交换 ,那这个比较并交换是怎么个意思呢?

首先他需要操作两个数,一个是自己读取的数,一个是自己读取过来改变的数,就如上面value,线程1读取了value的值为0 写入自己的工作内存,然后在进行value++的操作,将值改变为了1,这时候在写回主内存的时候,需要先看下是否主内存的value的值是否还是value=0,如果是则将自己改变的自增的value的值写入主内存,如果不是则将主内存的值读取最新的到自己的工作内存,再做一次value++,依次下去操作。这里就和我们所说的svn和git的版本控制很像了,你辛苦了一天写了几百行代码,现在下班了需要提交了,你肯定首先从仓库拉下,保证你的本地的代码是最新的才能去提交你写的代码。当然㘝你想覆盖别人的那也没办法,就是可能会被拉出午门问斩。囧囧囧

那我们现在是不是可以改造下呢?不多说,直接上代码

这里涉及到了一个底层的类Unsafe,我们后面再叙。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值