Java并发机制的底层实现原理

volatile的定义与实现原理

    先了解CPU的术语:内存屏障、缓冲行、原子操作、缓冲行填充、缓存命中、写命中、写缺失

    可见性:java线程内存模型确保所有线程看到这个变量的值是一致的

    Lock前缀的指令在多核处理器会引发两件事情:

    1)将当前处理器缓存行的数据

    2)写回操作会使在其他CPU里缓存了该内存地址的数据无效

volatile的使用优化

    追加64字节能够提高并发编程的效率:避免头节点和尾节点加载到同一个缓存行,使头、尾节点在修改时不会互相锁定

    以下两种方式不应该使用追加64字节:

                1)缓存行非64字节宽的处理器

                2)共享变量不会被频繁地写(锁的几率小)

synchronized的实现原理与应用

    synchronized有以下3种形式:

                1.普通同步方法,锁是当前实例对象

                2.静态同步方法,锁的是当前类的class对象

                3.对于同步方法块,锁是synchronized括号里配置的对象

   同步方法块用monitorenter与monitorexit指令实现,一个对象与一个monitor相关联,被持有后处于锁定状态。线程执行到时,尝试获取此monitor的所有权,即尝试获的对象的锁。

java对象头

    synchronized用的锁是存在java对象头的,如果对象是数组类型,虚拟机用3个字宽存储对象头,非数组用2个字宽。

锁的分级与对比

    锁有4种状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,级别只能从低到高

   只有一个线程时,无竞争关系,用偏向锁

   Java并发机制的底层实现原理

   轻量级锁加锁和解锁

Java并发机制的底层实现原理

原子操作的实现原理

了解术语:比较和交换、CPU流水线、内存顺序冲突(假共享:多个cpu修改同一缓存行的不同部分引起一个cpu修改失效。cpu必须清空流水线)

处理器实现原子操作:

    1)使用总线锁保证原子性

    2)使用缓存锁保证原子性

    第二种不适用的情况:

    1)操作的数据不能缓存在处理器内部,或操作的数据跨多个缓存行

    2)有些处理器不支持缓存锁定

CAS实现原子操作的三大问题

    1)ABA问题。可能之前变换有换回来了。解决思路是版本号。JDK的Atomic包提供了一个类AtomicStampedReference来解决,对比预期标志和预期引用

    2)循环时间长,开销大

    3)只能保证一个共享变量的原子操作

使用锁机制实现原子操作(除了偏向锁之外,jvm实现锁的机制都用了循环CAS