Java并发编程的艺术· 笔记(1)
1、volatile的原理
-
如何保持可见性:
1)将当前处理器缓存行的数据写回到系统内存。
2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。 -
使用优化
使用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里,成功则释放轻量级锁了,失败则释放锁(表示有竞争了)。
轻量级锁-->重量级锁:
- 另一个线程自旋获得锁失败,升级为重量级锁。
4、Java实现原子操作
-
CAS
存在三个问题:ABA(使用版本号:1A-2B-3A)、循环时间长浪费cpu时间、只能保证一个变量的原子操作(了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对 象里来进行CAS操作)。
-
锁
JVM内部实现了很多种锁 机制,有偏向锁、轻量级锁和互斥锁。有意思的是除了偏向锁,JVM实现锁的方式都用了循环 CAS。
(持续更新。。。)