一、什么是原子操作?如何实现原子操作?
假定有两个操作 A 和 B,如果从执行 A 的线程来看,当另一个线程执行 B 时,
要么将 B 全部执行完,要么完全不执行 B,那么 A 和 B 对彼此来说是原子的。

1、CAS可以认为是乐观锁:
*顾名思义就是保持一种乐观的态度,我们认为系统中的事务并发更新不会很频繁,即使冲突了也没事,大不了重新来一次。
*它的基本思想就是每次提交一个事务更新时,我们想看看要修改的东西从上次读取以后有没有被其它事务修改过,如果修改过,那么更新就会失败。
------常用实现方式就是加版本号。
2、悲观锁:总有刁民想害朕。。。
*基本思想就是每次一个事务读取某一条记录后,就会把这条记录锁住,这样其他的事务想要更新,必须等以前的事务提交或者回滚解除锁。
*悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)
3、悲观锁和乐观锁的比较:
乐观锁:
优势:并发性好,性能较高。
缺点:用户体验不好,录入半天,提交时被告知已经修改了。
悲观锁:
优势:会锁住记录,一个用户修改完成前,其它用户不饿能操作该记录。
缺点:并发性不好,性能不高

二、实现原子操作还可以使用当前的处理器基本都支持CAS()的指令,只不过每个厂家所实现的算法并不一样,每一个CAS操作过程都包含三个运算符:一个内存地址V,一个期望的值A和一个新值B,操作的时候如果这个地址上存放的值等于这个期望的值A,则将地址上的值赋值为新值B,否则不做任何操作。

CAS的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新值,否则不做任何事儿,但是要返回原值是多少,循环CAS就是在一个循环里不断的做cas操作,直到成功为止。

三、CAS实现原子操作的三个问题

1、ABA问题

因为 CAS 需要在操作值的时候,检查值有没有发生变化,如果没有发生变化 则更新,但是如果一个值原来是 A,变成了 B,又变成了 A,那么使用 CAS 进行 检查时会发现它的值没有发生变化,但是实际上却变化了。 ABA 问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量 更新的时候把版本号加 1,那么 A→B→A 就会变成 1A→2B→3A。

2、循环时间长开销大。

自旋 CAS 如果长时间不成功,会给 CPU 带来非常大的执行开销。

3、只能保证一个共享变量的原子操作

当对一个共享变量执行操作时,我们可以使用循环 CAS 的方式来保证原子操 作,但是对多个共享变量操作时,循环 CAS 就无法保证操作的原子性,这个时候 就可以用锁。

jdk中相关原子操作类的使用

AtomicInteger

①以原子方式将输入的数值与实例中的值相加,并返回结果

java原子变量 java中的原子操作是什么_java原子变量


②以原子方式将当前值加1,需要注意的是,这里返回的是自增前的值

java原子变量 java中的原子操作是什么_java原子变量_02