java中的锁:synchronized

  • synchronized
  • Synchronized概念
  • Synchronized三种用法
  • Synchronized的作用
  • synchronized锁优化
  • synchronized优缺点和使用场景


synchronized

Synchronized概念

  • Java对象头
    在Hotspot虚拟机中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充;Java对象头是实现synchronized的锁对象的基础,一般而言,synchronized使用的锁对象是存储在Java对象头里。
class oopDesc {
  friend class VMStructs;
 private:
  volatile markOop  _mark;//理解为对象头
  union _metadata {
    Klass*      _klass;
    narrowKlass _compressed_klass; //默认开启压缩
  } _metadata;
......
  • Mark Word

Mark Word用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等等。Java对象头一般占有两个机器码(在32位虚拟机中,1个机器码等于4字节,也就是32bit),下面就是对象头的一些信息:

java如何实现根据key值锁定对象 java锁的对象_java如何实现根据key值锁定对象

Synchronized三种用法

  • 当synchronized作用在实例方法时,监视器锁(monitor)便是对象实例(this);
  • 当synchronized作用在静态方法时,监视器锁(monitor)便是对象的Class实例,因为Class数据存在于永久代,因此静态方法锁相当于该类的一个全局锁;
  • 当synchronized作用在某一个对象实例时,监视器锁(monitor)便是括号括起来的对象实例

Synchronized的作用

  • 原子性:确保线程互斥的访问同步代码
  • 可见性:保证共享变量的修改能够及时可见
  • 有序性:有效解决重排序问题

    当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。

synchronized锁优化

无锁 --> 偏向锁 --> 自旋锁(轻量级锁) – > 重量级锁

  • 偏向锁:

偏向锁是在单线程执行代码块时使用的机制,如果在多线程并发的环境下(即线程A尚未执行完同步代码块,线程B发起了申请锁的申请),则一定会转化为轻量级锁或者重量级锁。

  • 自旋锁:

所谓自旋锁,就是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。

synchronized优缺点和使用场景

java如何实现根据key值锁定对象 java锁的对象_锁_02