Java中synchronized原理

synchronized是Java中的一个关键字,用于实现线程同步。它可以确保同一时刻只有一个线程能够访问被synchronized修饰的代码块或方法,从而保证数据的线程安全性。synchronized的原理主要基于Java虚拟机(JVM)的监视器锁(Monitor Lock)机制。以下是synchronized的原理和工作流程:

1、对象头

在Java中,每个对象都有一个对象头(Object Header),对象头包含了对象的元数据信息,如对象的哈希码、GC状态、锁状态等。synchronized就是通过对象头中的锁状态来实现线程同步的。
Java对象头的主要内容:

  • Mark Word:对象头中的一个关键部分,它用于存储对象的哈希码、GC状态、锁状态等信息。Mark Word的大小因JVM实现和对象类型而异,通常为4字节或8字节。Mark Word的布局会根据对象的状态(如无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态等)而变化。
  • Class Pointer:对象头中的另一个关键部分,它指向对象的类元数据信息。Klass Pointer的大小因JVM实现而异,通常为4字节或8字节。通过Klass Pointer,JVM可以访问对象的类信息,如类名、方法表、字段描述符等。
  • 数组长度:对于数组对象,对象头中还会包含一个数组长度字段,用于存储数组的长度。数组长度字段的大小因JVM实现而异,通常为4字节或8字节。
  • 对象状态:对象头中的元数据信息会根据对象的状态(如无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态等)而变化。例如,在偏向锁状态下,Mark Word中会包含偏向锁的信息;在轻量级锁状态下,Mark Word中会包含指向锁记录的指针;在重量级锁状态下,Mark Word中会包含指向监视器锁的指针。

以下是Java对象头的一个简单示例:

|-----------------|-----------------|-----------------|
|   Mark Word     |  Class Pointer  |   Array Length  |
|-----------------|-----------------|-----------------|

Java对象头是Java对象在内存中的布局的一部分,它包含了对象的元数据信息,如对象的哈希码、GC状态、锁状态等。对象头的主要作用是存储对象的元数据信息,以便JVM能够正确地处理对象。对象头中的元数据信息会根据对象的状态而变化。

2、锁状态:

Java虚拟机中的锁有四种状态:无锁状态、偏向锁、轻量级锁和重量级锁。synchronized在不同的锁状态下有不同的工作方式。

  • 无锁状态:对象刚被创建时,没有任何线程持有锁,此时锁处于无锁状态。
  • 偏向锁:当一个线程首次访问被synchronized修饰的代码块或方法时,JVM会偏向该线程,将锁状态升级为偏向锁。偏向锁的目的是减少无竞争情况下的锁开销。
  • 轻量级锁:当有其他线程尝试访问被synchronized修饰的代码块或方法时,如果锁处于偏向锁状态,JVM会尝试将锁状态升级为轻量级锁。轻量级锁通过自旋等待的方式来获取锁,避免了线程阻塞和唤醒的开销。
  • 重量级锁:当自旋等待超过一定次数或者有多个线程在等待锁时,JVM会将锁状态升级为重量级锁。重量级锁会导致线程阻塞和唤醒,从而降低了系统的并发性能。

3、锁状态

锁升级流程:

  • 无锁状态 -> 偏向锁:当一个线程首次访问被synchronized修饰的代码块或方法时,JVM会将锁状态升级为偏向锁,并将锁的持有者设置为当前线程。
  • 偏向锁 -> 轻量级锁:当有其他线程尝试访问被synchronized修饰的代码块或方法时,如果锁处于偏向锁状态,JVM会尝试将锁状态升级为轻量级锁。轻量级锁通过自旋等待的方式来获取锁,避免了线程阻塞和唤醒的开销。
  • 轻量级锁 -> 重量级锁:当自旋等待超过一定次数或者有多个线程在等待锁时,JVM会将锁状态升级为重量级锁。重量级锁会导致线程阻塞和唤醒,从而降低了系统的并发性能。

4、锁释放

当线程执行完被synchronized修饰的代码块或方法后,它会释放锁。释放锁的过程取决于锁的状态:

  • 偏向锁:释放偏向锁时,JVM会检查锁的持有者是否为当前线程,如果是,则将锁状态降级为无锁状态。
  • 轻量级锁:释放轻量级锁时,JVM会检查锁的持有者是否为当前线程,如果是,则将锁状态降级为无锁状态。
  • 重量级锁:释放重量级锁时,JVM会唤醒等待队列中的一个线程,并将锁的持有者设置为该线程。

总之,synchronized的原理是基于Java虚拟机的监视器锁机制,通过对象头中的锁状态来实现线程同步。synchronized在不同的锁状态下有不同的工作方式,包括偏向锁、轻量级锁和重量级锁。锁的状态会根据竞争情况自动升级,以提高系统的并发性能。

你可能感兴趣的:(java,开发语言)