【多线程与高并发】2-volatile

volatile

作用:

  • 保证线程可见性(MESI缓存一致性协议)
    M: 被修改(Modified) E: 独享的(Exclusive) S: 共享的(Shared) I: 无效的(Invalid)
  • 禁止指令重排序-CPU
    DCL单例
    Double Check Lock(双重检查)
    原语指令 (读写屏障用到):loadfence、storefence
    Synchronized并不能阻止重排序
  • 并不能保证原子性

双重检查既实现线程安全,又能够使性能不受到大的影响。那么什么是“双重检查加锁”机制呢?

  • 并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。
    进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。
    这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。

CAS(无锁优化 乐观锁 自旋)

CAS(要改的值,期望值,新值)
CPU原语支持,不允许中途被打断

ABA问题:
加version版本号
如果基础类型,无所谓;当引用类型(女朋友复合,中间经历了别的女人),可能会有问题

Unsafe类(等同于C/C++的指针)

  • 直接操作内存(allocateMemory.putXX)
  • 直接生成实例(allocateInstance)
  • 直接操作类或实例变量(objectFieldOffset、getInt、getObject)
  • CAS相关操作(CompareAndSwapOnject)

increment 递增

  • sync:效率可能低
  • AtomicXXX类
    解决同样的问题的更高效的方法,使用AtomXXX类;内部用了CAS操作,无需加锁
    AtomXXX类本身方法都是原子性的,但不能保证多个方法连续调用是原子性的
  • LongAdder:适用于并发线程特别多,内部用了分段锁,最终sum
posted @ 2021-12-19 21:41  辽河老男孩  阅读(38)  评论(0)    收藏  举报