CAS以及原子性与原子操作之间的不同

65 阅读2分钟

今天在学习CAS的时候发现了一个一个问题, 原子操作是什么?

这里讲课的老师还给我提到了数据库中的原子性, 这就让我犯了迷糊, 数据库中的原子性明明就是: 要么我在事务中的操作都完成要么在事务中的操作都不完成. 这和线程间相互操作有关系吗?

这里补充一下例子:

当前我们系统的业务需要记录下网站访问的用户数量, 我们这里通过变量的方式存储在内存中. 然后我们模拟一个线程池创建1000个线程同时向这个变量累加, 我们会发现这里最后打印的结果并不是1000而且结果还并不是一个确定的值.

伪代码:

//申明变量存储
int i = 1;
// 每次+1
i++; // 经过JVM分解后会先计算出i+1的值然后保存, 再赋值给i变量

先来了解一下为什么会发生这个问题?

很好想到. 这个时候我们的线程很多然后线程们相同拿到了同一个i值然后累加, 最后赋值. 这里就会出现问题了, CAS就是解决这种问题而诞生的.

CAS

CAS实际在赋前先获取到这个变量当前的值然后在去判断下这个值是否有改变,如果没有改变就赋值, 如果改变了就不赋值.

为什么做这种匪夷所思的问题呢? 刚刚问题的关键在哪? 在于赋值, 我们打断这层赋值就行了, 让他判断一下是不是有其他人在我的前面拿到了相同的值然后又在我的前面赋值了. 在他发现有人先赋值了后我们就重新开始[再来一遍]

原子性与原子操作的不同

原子性: 是数据库ACID中的保证事务要么都执行, 要么都不执行.

原子操作: 在大量线程修改同一个值(可以是引用类型)的时候保证他们不会因为事务过多导致重复更改.