总结锁策略, cas 和 synchronized 优化过程

1. 锁策略的总结

1. 乐观锁和悲观锁

2. 轻量级锁和重量级锁

3. 自旋锁和挂起等待锁

4. 普通互斥锁和读写锁

5. 可重入锁和不可重入锁

6. 公平锁和非公平锁(这里的公平表示遵循先来后到的规则)

  详细的可以看还有synchronized的优化过程:对于synchronized的总结-CSDN博客

  对于synchronized的来说它是自适应的,不是读写锁,是可重入锁,是非公平锁。 

2. CAS

  全称Compare and swap,字面意思:”比较并交换比较并且交换,的是内存和cpu寄存器。借助这个操作,就可以原子的完成很多复杂的操作,达成“无锁化编程”的效果。(CAS也不是万能的) 

1.简单的工作原理: 

1. 比较 A 与 V 是否相等。(比较)
2. 如果比较相等,将 B 写入 V。(交换)
3. 返回操作是否成功。
2. CAS的伪代码
下面写的代码不是原子的, 真实的 CAS 是一个原子的硬件指令完成的. 这个伪代码只是辅助理解
boolean CAS(address, expectValue, swapValue) {
 if (&address == expectedValue) {
   &address = swapValue;
        return true;
   }
    return false;
}

  我们可以带入一个场景有俩个线程同时要对address进行++,他会先判断address和expectValue是否相等,如果相等就会交换,不相等就不会进行交换。

3.Java标准库提供的原子类

总结锁策略, cas 和 synchronized 优化过程_第1张图片 

4.CAS的ABA问题

  你可以理解为你买的是一个翻新机,你因为你买的是一个新机器,实际上买到的是一个二手机器。外表看起来崭新的,但是已经是别人用剩的。CAS在使用的时候,关键要点是判定当前内存的值是否和寄存器的值是一样的,就进行修改,不一样就啥也不做。

 那对于ABA问题来说,什么时候会有bug呢?? 

  还可以假设一种情况你去银行取钱,结果卡住了,你多点了一下,此时产生了俩个线程,去尝试进行扣款操作(CAS)了,你会发现多按的一下并没有成功,因为俩个值并不相同就不会再扣一次,但是如果有第三个线程突然存了钱,那就出大问题了,就可能会多点的那一下扣去了。

对于ABA的解决方案:

  1. 约定数据变化是单向的(只能增加或者减少),不能是双向的。

  2.对于本身就必须双向变化的数据可以引入版本号,版本号这个数字就只能增加,不能减少了。

3.synchronized的优化过程

  synchronized 背后设计到了很多的“优化手段”。

  1. 锁升级:偏向锁->轻量级锁->重量级锁

  2. 锁消除:自动干掉不必要的锁。

  3. 锁粗化: 把多个细粒度的锁合并成一个粗细粒度的锁,减少了锁竞争的开销。

 可以看这一篇:对于synchronized的总结-CSDN博客

你可能感兴趣的:(java)