【问题标题】:Which thread will get the lock?哪个线程会获得锁?
【发布时间】:2010-10-17 10:17:32
【问题描述】:

假设我们有多处理器机器和多线程应用程序。如果两个线程可以访问同步方法并且它们同时执行,那么哪个线程将获得锁? 或者会发生什么?

谢谢

【问题讨论】:

  • 我猜,VM 将不得不抛硬币。
  • 这是否意味着如果两个线程都尝试在循环中获取锁,则允许 VM 饿死一个线程?
  • @Peter G,是的,看看我的回答。
  • @Peter G:按照规范可以。但是一个聪明的实现会有一些方法来解决它(比如大概的到达顺序)。

标签: java multithreading concurrency synchronization


【解决方案1】:

行为将是非确定性的(即,任何一个线程都可能获得锁),并且可能因执行而异。这是因为它取决于特定的 JVM 实现以及线程的特定调度。

根据这篇文章,JVM 规范对公平性没有任何限制:

公平
Java 内存模型没有为线程或抢占式多线程指定任何公平要求。一个线程可以拒绝将 CPU 交给另一个线程并使系统陷入死锁。对其他线程的公平规则由各个 JVM 实现定义。

也就是说,除非您仔细同步您的程序,否则理论上一个线程可能会被调度程序饿死。

【讨论】:

  • 我也不认为在那个级别会有任何“同时”。一个线程将获得锁,只是因为先到达那里。无需抛硬币。
【解决方案2】:

关键是没有“同时”这样的东西。两者中的一个将获得锁,但您无法知道是哪一个。

不存在“同时”这样的事情,因为从广义上讲,锁是某种东西,它一次只选择并执行一个线程。

这自然是在一个可以一次执行一条指令的纯单处理器系统中完成的。在多处理器系统上,通常会有一些硬件设备“锁定”处理器以防止它们同时执行。

【讨论】:

  • 为什么不是“同时”。我们谈论的是多处理器硬件......
  • 但是管理锁的代码必须以某种方式进行序列化。
  • @Feras, aioobe: 即使在多处理器系统中,也存在不能同时执行的操作(参见en.wikipedia.org/wiki/…),任何 sychrnonized 的实现都必须使用这样的操作,以确保没有两个线程同时进入锁。
  • 是的,当然,这就是锁定的重点。我(我也怀疑 Feras)正在询问两个线程同时请求锁的情况。这肯定是可能的......
  • ...但是请求该锁的一部分是执行原子指令,而该部分不能“同时”执行。
猜你喜欢
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多