【问题标题】:Query on implementation of lock mechanism in java查询java中锁机制的实现
【发布时间】:2023-12-25 10:07:01
【问题描述】:

正如 Doug Lea 的“Java 中的并发编程”中提到的,

Object 类(及其子类)的每个实例都拥有一个锁,该锁在进入同步方法时获得,并在退出时自动释放。

JVM 是否完全在用户空间实现锁机制?

JVM 是否依赖操作系统内核空间系统调用来实现锁定?请提供实现锁机制的代码参考。

注意:Java 多线程的新手

【问题讨论】:

  • 这完全独立于实现。在 linux 上,您可以使用 strace 查看任何系统调用。你很可能会看到FUTEX 来电。

标签: java jvm mutex


【解决方案1】:

JVM是否完全在用户空间实现锁机制?

大部分,但不完全。

JVM 是否依赖操作系统内核空间系统调用来实现锁定?

它尝试处理用户空间中的锁,但如果暂时无法获得锁,它会退回到操作系统锁。

参考实现在 OpenJDK 中,您可以免费下载。

Java 多线程新手

被埋没/迷失在细节中可能不是很有帮助。

【讨论】:

  • 了解锁实现的原因,因为在方法级别使用synchronized 关键字对我来说是有意义的,因为我们拥有内在锁。但是synchronized(this){} 对我来说没有意义。为什么我们除了拥有内在锁之外还需要其他东西(this)来创建临界区?
  • @overexchange 只有锁定线程之间共享的对象才有意义。有时,一个或两个线程中的这个共享对象是一个传递给它的对象,即不是this 有时锁定整个对象没有意义,您需要多个单独的锁来保护不同的字段集。有时您想使用类锁。例如。 synchronised(MyClass.class)
  • 我的问题是,锁定MyClass.classthis 等是什么意思?尽管我们有一个可以获取/释放的内在锁(它是一个独立的实体,由 JVM 维护)?这就是我们在方法级别说synchronized 时所做的事情。在块语法中,我不确定我们在做什么,当我们说synchronized(this){}synchronized(MyClass.class){} 时,我们实际上在这里锁定了什么?我们不是在块语法情况下获得了内在锁吗?为什么我们需要依赖thisMyClass.class来获取/释放内部锁?
  • @overexchange 当你获得一个锁时,它是嵌入在一个对象中的那个。这就是为什么您必须指定要锁定的对象,或者对于同步方法,它会隐式锁定类对象或实例。
  • 好的。因此,我们为同步方法锁定实例。那么,同一对象的另一个线程部分如何移动并到达该同步方法并在该同步方法处被阻塞(自旋锁(busywait))?我觉得locking an object 的意思是,该多线程对象中不应发生其他活动。