
悲观锁,它们认为当使用数据的时候一定有其它线程来修改,所以在获取数据的时候就会加锁,确保不会被其它线程修改。
synchronized代码块:
public synchronized void update() { //同步资源 }
代码块:
public void update() { Lock lock = new ReentrantLock(); lock.lock(); try { //同步资源 } finally { lock.unlock(); } }
,它认为使用数据的时候不会有别的线程来修改数据,所以不会加锁。只要在自身要进行update操作的时候,才会去判断之前的数据是否被别的线程修改了。如果没有被修改则会修改成功,相反则会修改不成功。这里最典型的是java.util.concurrent并发包中的递增操作就通过CAS自旋实现的。
CAS代码块:
public class TestLock { AtomicInteger atomicInteger = new AtomicInteger(0); public int add() { return atomicInteger.incrementAndGet(); } }

总结
- ABA问题(JDK1.5之后已有解决方案):CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。ABA问题的解决思路就是在变量前面添加版本号,每次变量更新的时候都把版本号加一,这样变化过程就从“A-B-A”变成了“1A-2B-3A”。
- 循环时间长开销大:CAS操作如果长时间不成功,会导致其一直自旋,给CPU带来非常大的开销。
- 只能保证一个共享变量的原子操作(JDK1.5之后已有解决方案):对一个共享变量执行操作时,CAS能够保证原子操作,但是对多个共享变量操作时,CAS是无法保证操作的原子性的。
文章来源: https://blog.csdn.net/qq_33540203/article/details/92597837