Java 互斥是如何在内部实现的

Java 互斥是如何在内部实现的,java,multithreading,synchronization,mutex,Java,Multithreading,Synchronization,Mutex,我花了一些时间试图理解互斥是如何在几种语言中实现的。有多个链接描述了这个主题(*),但如果我理解正确的话,硬件提供的只是一些原子操作,可能有助于区分现在应该轮到谁 在软件中,这总是用于忙等待(尝试CAS或测试,如果不成功,设置并等待while cycle),但是调度程序如何知道现在我应该从CPU中删除进程/线程,因为它所做的只是等待?在操作系统中是否提供了一些支持,例如Java同步使用这些支持来发出“我被阻止了,请让其他线程运行”的信号?我想是的,因为忙等待是使用lock()的另一种选择;(因此

我花了一些时间试图理解互斥是如何在几种语言中实现的。有多个链接描述了这个主题(*),但如果我理解正确的话,硬件提供的只是一些原子操作,可能有助于区分现在应该轮到谁

在软件中,这总是用于忙等待(尝试CAS或测试,如果不成功,设置并等待while cycle),但是调度程序如何知道现在我应该从CPU中删除进程/线程,因为它所做的只是等待?在操作系统中是否提供了一些支持,例如Java同步使用这些支持来发出“我被阻止了,请让其他线程运行”的信号?我想是的,因为忙等待是使用lock()的另一种选择;(因此它们不应该是相同的)

*资料来源:


在Linux JDK soure C代码中使用
pthread
库,它是标准C库的一部分。这反过来又使用Linux内核
futex
特性(
manfutex
)。据我所知,这是使用内核调度器实现的,它将调用线程置于睡眠状态,并在收到信号时将其唤醒

调度器本身依赖于定时器中断(硬件)来工作——本质上,每次定时器中断到来时,调度器都必须检查当前用户空间线程是否需要/必须挂起,如果需要,则必须选择其他线程

这里有几个更清晰、更详细的链接:

  • 罗伯特·洛夫(Robert Love)的《Linux内核开发》(但是,奇怪的是,它没有一个提到futex)和另一本书(其中确实提到futex,但主要是参考外部论文):Kerrisk的《Linux编程接口》(The Linux Programming Interface)

  • 这是一个书本级的话题。这本书:

    多处理机编程的艺术 莫里斯·赫利希,尼尔·沙维特 ISBN-13:978-0123973375


    事实上,还有一个原因是,操作系统提供的用户级互斥量远远不止使用硬件原语。用户级互斥体与操作系统的调度算法密切相关

    理解Linux内核 Daniel P.Bovet,Marco Cesati ISBN-13:978-0596005658


    在其核心中,互斥体是内核使用的内核对象。它会影响线程的状态(可运行、等待等),而调度程序又会使用这些状态来做出决策。这就是为什么互斥锁并不真正“便宜”,并且经常与优化(如旋转锁)结合使用,旋转锁试图避免内核调用。调度程序不仅由计时器触发。更多(3?!)代码路径触发linux内核中的调度程序。试图获得一个已经被使用的互斥是一个展示。只是一个问题,我想知道我是否理解正确。这意味着,如果我的线程被阻塞,它仍然负责,直到调度程序被唤醒,并看到线程什么也不做?不-在操作系统不可知的术语中-您的应用程序线程使用“takeMutex()”调用内核。在内核空间中的实现中,
    takeMutex()
    可能会看到已经使用了互斥,并以某种形式调用调度程序。调度程序的计时器触发器主要用于向处于“运行”状态的所有线程授予“公平”时间片。谢谢用户,明白了。我认为还有一些对信号量的支持,与此非常相似。是的,有一整套“内核对象”,互斥就是其中之一。根据操作系统的不同,这还可以包括文件句柄等。