美文网首页
2. Java并发机制的底层实现原理

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

作者: 星冉子 | 来源:发表于2020-02-13 10:07 被阅读0次

    Volatile

    volatile认为是轻量级的synchronized,使用和执行成本更低,不会引起上下文切换和调度;

    volatile修饰的变量写操作时的汇编代码会多一条:lock指令,作用:

    1. 将当前处理器缓存行数据写回内存;

    2. 一个处理器的缓存回写会使其他缓存了该内存地址的数据无效;

    缓存一致性协议:每个处理器通过嗅探总线数据来保证数据一致;

    需要多个线程区写同一个共享变量,volatile变量是不合适的

    synchronized

    实现原理:JVM基于进入和退出monitor对象实现,进入前代码经编译后插入monitorenter指令,退出时插入monitorexit指令;

    任何对象都有一个monitor,monitorenter和monitorexit是配对的;

    锁信息的存储:存储在Java对象头中的mark word中;

    锁有4种状态:无锁、偏向锁、轻量级锁、重量级锁,锁只能升级不能降级,是为了提高获得和释放锁的效率;

    偏向锁:

    引入目的:通常锁由一个线程多次获得,为了减少这种情况下的获得代价;

    实现原理:Java对象头的Mark Wod中存储了偏向锁的线程ID和锁状态,存在竞争时才释放锁或者竞争锁;

    加锁:线程进入同步块时,将线程ID记录到对象的头中,下次进入只需要检测头信息即可重新获得,没有信息才使用CAS竞争锁;

    解锁:退出同步代码块或者有线程竞争时;

    关闭:Java默认开启了偏向锁,如果确定程序大多数都处于竞争,可以通过JVM参数关闭偏向锁,这时会进入轻量级锁;

    轻量级锁:

    加锁:线程将对象的MarkWord复制到线程的栈空间并修改然后写回对象,失败时通过自旋获取锁;

    解锁:写回对象的MarkWord,若失败表示锁存在竞争,锁升级为重量级锁,重量级锁时其他线程都是阻塞

    锁对比

    原子操作

    处理器如何实现:

    总线锁:处理器操作时锁总线,让其他处理器不能操作;

    缓存锁:保证内存的缓存一致(即volatile的缓存一致性);

    Java如何实现:锁、CAS(利用处理器的CMPXCHG指令)

    CAS的问题及解决:

    1. ABA问题;解决:数据加上版本号;Java实现:AtomicStampedReference;

    2. 循环时间长开销大;解决:利用处理器的pause指令延迟执行;

    3. 只能保证一个共享变量的原子操作;解决:锁或者将多个变量包装到一个变量;Java实现:AtomicReference;

    JVM中除了偏向锁,其他锁机制都用到了CAS;

    相关文章

      网友评论

          本文标题:2. Java并发机制的底层实现原理

          本文链接:https://www.haomeiwen.com/subject/tcnknctx.html