在Java中,synchronized
关键字用于实现线程间的同步,确保同一时刻只有一个线程能够访问被同步的代码块或方法。当一个线程获得synchronized
锁定后,其他试图访问同一锁的线程将被阻塞,直到锁被释放。
synchronized
锁有两种基本形式:
- 同步方法:通过在方法声明前加上
synchronized
关键字,整个方法体被保护,同一时间内只能有一个线程访问该方法。
public class MyClass { public synchronized void synchronizedMethod() { // 执行同步代码... } }
- 同步代码块:通过
synchronized(object)
的方式指定一个对象作为锁,只有持有该锁的线程才能执行同步代码块。
public class MyClass { private Object lock = new Object(); public void synchronizedBlock() { synchronized (lock) { // 执行同步代码... } } }
synchronized
锁的升级机制是Java虚拟机(JVM)为了提高并发性能而引入的一种优化措施,它发生在HotSpot虚拟机中,主要包括以下四种状态:
- 无锁状态:对象未被任何线程锁定。
- 偏向锁(Biased Locking):当只有一个线程访问同步代码块时,会偏向于该线程,仅记录该线程ID,后续该线程进入同步代码块时无需再进行加锁操作。
- 轻量级锁(Lightweight Locking):当第二个线程尝试获取偏向锁时,偏向锁失效,转变为轻量级锁。轻量级锁通过CAS(Compare and Swap)操作尝试获取锁,如果获取失败(即已经有其他线程持有了锁),会进行自旋(spin)尝试,短时间内不停尝试获取锁,减少上下文切换的开销。
- 重量级锁(Heavyweight Locking):如果自旋一定次数后仍无法获取锁,轻量级锁会膨胀为重量级锁,此时会挂起当前线程,使其进入阻塞状态,等待锁持有者释放锁。重量级锁会消耗更多的系统资源,但它能保证公平性和互斥性。
- 4种状态的转换关系如下图所示:
这种锁升级机制旨在减少不必要的上下文切换,从而提高程序在多线程环境下的执行效率。在Java 6及以后版本的HotSpot JVM中,默认开启了锁升级优化策略。