Java并发编程的艺术· 笔记(1)

1、volatile的原理

  1. 如何保持可见性:

    1)将当前处理器缓存行的数据写回到系统内存。
    2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。

  2. 使用优化

使用volatile变量时,可以用一种追加字节的方式来优化队列出队和入队的性能

是不是在使用volatile变量时都应该追加到64字节呢?不是的。

例如场景:缓存行非64字节宽的处理器 ;

​ 共享变量不会被频繁地写。

2、Synchonized

Synchonized在JVM里的实现原理,JVM基于进入和退出Monitor对 象来实现方法同步和代码块同步。

synchronized用的锁是存在Java对象头里的。如果对象是数组类型,则虚拟机用3个字宽 (Word,即12 Bytes)存储对象头(Mark Word,存储到对象类型数据的指针、数组长度),如果对象是非数组类型,则用2字宽存储对象头。

的Mark Word里默认存储对象的HashCode、分代年龄和锁标记位。

3、无锁-偏向锁-轻量级锁-重量级锁

偏向锁:修改对象头Mark Word里的线程ID-----CAS操作

轻量级锁的加锁:线程复制Mark Word到栈,CAS尝试把Mark Word替换成指向锁记录的指针,成功则获得锁,失败则自旋,再失败则升级成重量级锁,阻塞。

轻量级锁的释放:CAS尝试把锁记录替换回对象头Mark Word里,成功则释放轻量级锁了,失败则释放锁(表示有竞争了)。

轻量级锁-->重量级锁:

  1. 另一个线程自旋获得锁失败,升级为重量级锁。

4、Java实现原子操作

  1. CAS

    存在三个问题:ABA(使用版本号:1A-2B-3A)、循环时间长浪费cpu时间、只能保证一个变量的原子操作(了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对 象里来进行CAS操作)。

  2. JVM内部实现了很多种锁 机制,有偏向锁、轻量级锁和互斥锁。有意思的是除了偏向锁,JVM实现锁的方式都用了循环 CAS。

(持续更新。。。)

posted @ 2019-04-26 17:20  张十六  阅读(248)  评论(0编辑  收藏  举报