【Java并发编程】 乐观锁 悲观锁 CAS(比较交换)

一. 乐观锁与悲观锁

1. 悲观锁

悲观锁总是假设每次对临界区(共享数据)操作都会产生冲突,因此他所有操作都是小心翼翼的,也就是说当多个线程同时需要访问临界区,宁可牺牲性能(阻塞线程的执行)

2. 乐观锁

乐观锁则总是假设每次对临界区的操作总是没有冲突的,自然就不需要阻塞了,所以所有的线程都可以在不停顿的状态下持续执行。

二 . CAS(比较交换)

1. CAS与乐观锁

CAS是乐观锁的一种实现方式,前面介绍乐观锁时,提到了乐观锁每次都是假设所有操作是没有冲突的,那么当真的遇到冲突时,乐观锁是如何处理的?事实上,一旦检测到冲突产生,CAS就会重复当前操作直到没有冲突产生。

2. 详解

CAS使用的是无锁策略,所以其不会阻塞、不会死锁,并且线程间的相互影响比有锁的方式要小。更为重要的是,使用无锁策略不会有锁竞争带来的开销,以及线程间频繁调度的开销,因此他比有锁的方式性能更为优越。
CAS算法过程是这样的,GAS(V,E,N)包含三个参数:

  • V:表示要更新的变量
  • E:表示预期值
  • N:表示新的值

当V==E时,才会将V=N;
当V!=E时,说明其他线程已经做了更新,当前线程什么都不做;
最后CAS(V,E,N)返回当前V的值。

上面的步骤详细点说就是:当CAS对数据进行操作,它总是认为可以成功完成操作,当多个线程使用CAS操作同一个数据时,只有一个能成功操作,其他的会失败。失败的线程不会被挂起,仅仅被告知失败,CAS允许失败的线程再次尝试或放弃操作。

简单地说就是:CAS需要你给出一个期望值,即你认为操作变量现在是什么值,如果变量的值与你所期望的值不同,说明其被修改过了,这时就要重新尝试或放弃。

猜你喜欢

转载自blog.csdn.net/HuaLingPiaoXue/article/details/90109942