在Java中,synchronized
关键字用于实现线程同步,以保护共享资源的访问。在多线程环境中,Java的锁机制会根据不同的线程竞争情况,动态地对锁的状态进行升级,以提高程序的执行效率。锁的升级过程大致可以分为几种状态:无锁状态、偏向锁、轻量级锁和重量级锁。
1. 无锁状态
初始状态为无锁状态,在没有线程请求锁的情况下,锁处于无锁状态,任何线程都可以访问相应的资源。这种状态下无需任何同步机制,执行效率较高。
2. 偏向锁
当一个线程第一次请求锁时,JVM会将锁的状态设置为偏向锁,并把锁对象的偏向线程ID设置为这个线程ID。这意味着,如果后续的线程再次请求这个锁,并且是同一个线程,就不会进行任何额外的竞争,直接获取锁。这种机制大大减少了同步中的开销。
public class BiasedLockExample {
public synchronized void biasedLockMethod() {
System.out.println(Thread.currentThread().getName() + "获取了偏向锁");
// 执行一些操作
}
public static void main(String[] args) {
BiasedLockExample example = new BiasedLockExample();
Thread t1 = new Thread(example::biasedLockMethod);
t1.start();
}
}
3. 轻量级锁
当有多个线程争抢偏向锁,且偏向锁被其他线程请求时,JVM会将锁的状态升级为轻量级锁。此时,轻量级锁会使用一个标志位进行管理,如果当前线程获取锁成功,其他线程需要通过自旋的方式来尝试获取锁。这种方式的开销比重量级锁要小。
public class LightweightLockExample {
private final Object lock = new Object();
public void lightweightLockMethod() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "获取到了轻量级锁");
// 执行一些操作
}
}
public static void main(String[] args) {
LightweightLockExample example = new LightweightLockExample();
Thread t1 = new Thread(example::lightweightLockMethod);
Thread t2 = new Thread(example::lightweightLockMethod);
t1.start();
t2.start();
}
}
4. 重量级锁
当轻量级锁被其他线程长时间占用,这时可能会导致自旋的开销变得很大。为了避免锁竞争造成的性能损耗,JVM会将轻量级锁升级为重量级锁。此时所有的请求锁的线程将被挂起,只有释放锁的线程才能唤醒被挂起的线程。
public class HeavyweightLockExample {
private final Object lock = new Object();
public void heavyweightLockMethod() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "获取到了重量级锁");
// 执行一些操作
try {
Thread.sleep(2000); // 模拟长期占用锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
HeavyweightLockExample example = new HeavyweightLockExample();
Thread t1 = new Thread(example::heavyweightLockMethod);
Thread t2 = new Thread(example::heavyweightLockMethod);
t1.start();
t2.start();
}
}
小结
上面的示例通过不同的锁状态演示了Java
中的synchronized
关键字是如何管理多个线程之间的竞争关系的。从无锁到偏向锁、轻量级锁再到重量级锁,这一系列过程旨在动态优化锁的性能,以适应实际的线程竞争情况。理解锁的升级过程是优化多线程程序性能的重要一环,能帮助开发人员在设计系统时更好地使用锁机制。