获取和释放java监视器锁(同步块、可重入锁等)是否需要上下文切换到内核空间?

Shu*_*ain 3 java concurrency jvm locking java.util.concurrent

AFAIK,Java 中的每个对象都有一个标记字。第一个字(标记字)用于存储锁定信息,如果只有一个线程正在获取锁,则通过标志;如果不同线程之间存在争用,则通过指向锁定监视器对象,并且在这两种情况下,比较和交换结构用于获取锁。

但根据此链接 - https://www.baeldung.com/lmax-disruptor-concurrency

为了处理写入争用,队列通常使用锁,这可能会导致上下文切换到内核。当发生这种情况时,所涉及的处理器可能会丢失其缓存中的数据。

我缺少什么?

Hol*_*ger 5

当锁定无竞争synchronized或解锁时,标准Lock实现都不需要上下文切换到内核。这些操作确实可以归结为原子 cas 或 write。

\n\n

性能的关键方面是争用,即当尝试获取监视器或锁时,它\xe2\x80\x99s 不可用。等待监视器或锁的可用性意味着将线程置于等待状态,并在资源可用时重新激活它。性能影响如此之大,以至于您根本不需要担心 CPU 缓存。

\n\n

因此,典型的实现会执行一定量的旋转,重新检查监视器的可用性或在循环中锁定一段时间(当有机会在该时间内变得可用时)。这通常与 CPU 核心的数量相关。当资源届时可用时,这些成本就可以避免。然而,这通常要求允许获取是不公平的,因为旋转获取可能会超过已经在等待的线程。

\n\n

请注意,链接的文章在您引用的句子之前说:

\n\n
\n

由于消费者和生产者之间的速度差异,队列通常总是接近满或接近空。

\n
\n\n

在这种情况下,更快的线程迟早会进入条件等待,等待队列中的新空间或新项目,即使它们在没有争用的情况下获取了锁。因此,在这个特定场景中,相关成本确实存在,并且在使用简单的队列实现时是不可避免的。

\n