synchronized的底层实现 JDK早期的 重量级- OS 后来的改进 锁升级的概念: 我就是厕所所长(一 、二 ) sync (Object) markword记录这个线程ID (偏向锁) 如果线程争用:升级为自旋锁 10次以后, 升级为重量级锁 - OS

  1. 针对synchronized比Atomic原子类慢的说法并不准确===>实际测试
  2. 锁只能升级不能降级===>jvm的实现中可以做到这一点
  3. jvm中没有给出synchronized的实现规范,是hotspot自己实现的
  4. synchronized锁的是对象不是代码

什么时候使用自旋锁比较好===>Atmoic、Lock用的都是自旋锁

  1. 占cpu,但不访问操作系统;在用户态解决锁的问题,不经过内核态;效率上比经过os的加减锁高一点
  2. 执行时间短并且线程数比较少的时候用自旋锁
  3. 执行时间长并且线程数比较多的时候用系统锁

synchronized加锁的时候不能用String常量(对象也尽量少用)、Integer、Long这些基本数据类型

  1. 所有字符串常量用的都是 同一个字符串常量
  2. 否则自己写的代码会与别的类库的代码上锁时产生冲突,造成不可预知的错误
  3. 同一个线程可能会造成重入;不是同一个线程可能会造成死锁
  4. Integer中也会有特殊的处理,其中的值只要变一下就会产生新的对象(-128~127

🌟synchronized优化

  1. 锁优化的过程贯穿在锁的各个部分!
  2. 锁粒度变细和锁粒度变粗
  3. 竞争不是很激烈,粒度细一些(Fine)
  4. 竞争激烈争用特别频繁的时候,粒度粗一些(Coarse)
    1. 一段代码中有好多好多细碎的锁,还不如将其合并为一个大锁===>会降低争用,只要代码写得足够好,就不会产生死锁(程序没问题,有更好的写法)
    2. 一张表所有的行上都加锁还不如直接给表加上锁
  5. 概念上的东西,没有特殊的规范
  6. 锁定某对象o,如果o的属性发生改变,不会影响锁的使用;但是如果o变成另外一个对象,则锁定的对象发生改变,应该避免将锁定对象的引用变成另外的对象===>锁是用对象头上的markword中的两位来表示的;要想避免无意中的改变,可以将要上锁的对象,设置为final
  7. 不要用String类型来作为锁