【664、sychornized 为什么是重量级锁,从操作系统层面讲】

635 阅读2分钟

在操作系统层面,每个 Java 线程都与操作系统线程相对应。每个线程都有一个线程栈,其中包含了线程正在执行的方法和变量等信息。在 Java 中,每个对象都有一个与之相关联的监视器(也称为内部锁或互斥锁)。当线程要进入一个 synchronized 方法或块时,它必须先获取这个对象的监视器。如果这个对象的监视器已经被其他线程获取了,那么当前线程就会被阻塞,直到监视器被释放。

为了实现这个锁机制,JVM 通过操作系统提供的原生线程同步机制来实现 synchronized 关键字。在大多数操作系统中,线程同步机制包括两种:用户态线程同步和内核态线程同步。用户态线程同步的开销很小,因为它完全由用户程序实现,不需要切换到内核态,但是它只能同步同一进程内的线程。当需要同步多个进程的线程时,就需要使用内核态线程同步。内核态线程同步的开销很大,因为需要将线程从用户态切换到内核态,这个过程需要进行上下文切换,开销很大。

在 Java 中,如果一个 synchronized 块或方法正在执行,那么它所关联的对象就会被加锁。这个锁在操作系统层面实际上是一个内核态的互斥锁。当一个线程要进入一个被锁住的 synchronized 块或方法时,它必须等待锁被释放,这个等待过程需要将线程从用户态切换到内核态,这个过程很耗时,因此 synchronized 被称为“重量级锁”。

当需要同步的代码量很小的时候,使用 synchronized 锁可能会比较浪费资源。因此,在 Java 5 中引入了轻量级锁和偏向锁的概念,以提高同步的效率。轻量级锁和偏向锁都是在竞争不激烈的情况下使用的,而 synchronized 锁则是在竞争激烈的情况下使用的。