1.synchronized加锁的对象有哪些?
- object对象(new 出来的对象)
场景:1.synchronized修饰非静态方法 2.synchronized(object)同步代码块传入的object对象 - class单例对象
场景:1.synchronized修饰静态方法 2.synchronized(class)同步代码块传入的class对象 - 常量池对象
场景:synchronized(“123”)同步代码块传入的常量池对象
2.synchronized中的锁升级是否可逆?
不可逆。synchronized锁一共有4种状态,级别从低到高依次是:无锁状态 --> 偏向锁状态 --> 轻量级锁状态 --> 重量级锁状态,这几种状态会随着竞争情况逐渐升级。锁可以升级但不能降级。
3.偏向锁、轻量级锁、重量级锁的区别
锁 | 获得锁的方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
偏向锁 | 在对象头和栈帧中的锁记录里面存储偏向的线程ID | 加锁和解锁不需要额外的消耗,和执行非同步方法相比仅存在纳秒级的差距 | 如果线程存在锁竞争,会带来额外的锁撤销的消耗 | 只有一个线程访问同步块 |
轻量级锁 | CAS操作成功更新对象Mark Word指向Lock Record的指针 | 竞争的线程不会阻塞,提高了程序的响应速度 | 如果始终得不到锁竞争的线程,使用自旋会消耗CPU | 追求响应时间,同步块执行速度非常快 |
重量级锁 | 获取到对象的monitor | 线程竞争不使用自旋,不会消耗CPU | 线程阻塞,响应时间缓慢 | 追求吞吐量,同步块执行时间长 |
4. 有没有线程是不能获取偏向锁的?
当一个对象已经计算过一致性哈希码之后,它就再也无法进入偏向锁状态,当一个对象当前正处于偏向锁状态,又收到需要计算其一致性哈希码请求时,它的偏向状态会被立即撤销,并且锁会膨胀为重量级锁。