Java并发编程艺术读书笔记一
- volatile
轻量级的同步机制,有volatile修饰的变量在进行写操作的时候会多出一条lock前缀的指令,比如lock addl $0 x 0,(%esp)。lock前缀的指令在多核处理器下面会引发下面两件事情:①将当前处理器缓存行的数据写回到系统内存。②这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。③volatile写代表锁的释放,volatile读代表锁的获取。
synchronized
对于普通方法,锁是当前实例对象。对于静态方法,锁是当前类的Class对象。对于同步方法块,所示synchronized括号里面配置的对象,代码块的同步是基于monitorenter和monitorexit来实现的。Java对象头
synchronized用的锁是存在JAVA对象头里面的。JAVA对象头里的Mark Word默认存储了对象的HashCode,分代年龄和锁标记。偏向锁
偏向锁使用了一种等到竞争出现才释放锁的机制。它首先会暂停拥有偏向缩的线程,然后检查持有偏向缩的线程是否活着,如果线程处于不活动状态,则将对象头设置为无锁状态;如果线程仍然活着,持有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark Word要么重新偏向于其他线程,要么恢复到无锁或者标记对象不适合作为偏向锁,最后唤醒暂停的线程。可以通过JVM参数关闭偏向锁:-XX:-UseBiasedLocking=false。轻量级锁
使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程尝试使用自旋来获取锁。重量级锁
自旋获取锁失败,轻量级线程就会转换成重量级线程。总线锁
所谓总线锁就是使用处理器提供的一个LOCK #信号,当一个处理器在总线上输出此信号时,其他处理器请求将被阻塞住,那么该处理器可以独占共享内存。ABA问题
如果一个变量的值从A变到B又变到A,此时可以通过版本来感知到这一变化,注意版本思想在实际开发工作中的灵活使用。CAS
在修改一个变量值的时候先判断一下变量当前的值是否和我们期望的值一样,入股一样就修改,不一样就不修改。