ABA问题
在两个线程同时对一个资源进行CAS的时候,会导致ABA问题,就是在线程A进行了一次CAS,这个时候线程B准备对进行C,但在这之前,线程A又进行了一次CAS,并且第二次的CAS把值恰好又变回了最原来的值,这导致线程B的CAS成功了,但这时,虽然值是一样的,其实值已经不是原来的那个值了,版本不一样了。
可以为变量增加版本号来解决这个问题,譬如AtmoicStampedReference就有一个version字段
Synchronized 同步锁
它是JVM提供的,而LOCK是jdk提供的
先来了解几种锁的概念
- 自旋锁:没能获取锁的话就一直对锁来进行比较while
自旋锁有2种,把代码里的的Demo2_SpinLock和ABA看懂,就懂了 - 乐观锁 每次读取之前,认为没有人会去修改,所以并不加读锁
悲观锁 每次读取之前,都认为有人会去修改,所以每次读取之前都会加读锁 - 独占锁 写锁
共享锁 读锁 多用于限流 - 可重入锁 本线程能不能2次拿到同一把锁
不可重入锁 - 公平锁 是否按先来后到的顺序获得锁
Synchronized 独占、不公平、可重入锁
锁消除:
举例,StringBuffer用了Synchronized,但如果只在一个线程内使用的话,那么JIT会做优化,做锁消除,除去了加锁、解锁的操作,提高了性能
锁粗化
在代码里连续对几段代码进行加锁,其实可以只进行一次加锁就可以达到同样的效果,JVM和jIT就会做锁粗化的优化