【问题标题】:Java Thread.suspend precise semanticJava Thread.suspend 精确语义
【发布时间】:2015-07-30 05:29:12
【问题描述】:

这个问题不是关于 Thread.suspend 的替代品。 这是关于使用 Thread.suspend 实现偏置锁的可能性,(我相信)不能使用 Thread.interrupt 或类似的替代方案来实现。

我知道 Thread.suspend 已被弃用。

但我想知道 Thread.suspend 的确切语义。

如果我调用thread1.suspend(),我是否保证在thread1完全停止之前被阻塞?如果我调用thread1.resume(),这个调用是否对其他线程可见?

此外,如果我成功挂起一个线程,该线程是否会在某个安全点被挂起?我会看到它的中间状态(因为即使在未正确同步的程序中,Java 也会无中生有地禁止值,我不相信这是允许的)还是看到一些乱序(如果挂起是异步请求,那么我肯定会看到那种东西)?

我想知道这些,因为我想在 Java 中实现一些玩具非对称锁(如 HotSpot 中的 BiasedLock)。使用 Thread.suspend,您可以实现类似 Dekker 的锁,而无需存储负载障碍(并将负担转移到稀有路径)。我的实验表明它有效,但由于 Thread.sleep 足以等待远程上下文切换,我不确定这是保证行为。

顺便问一下,有没有其他方法可以强制(或检测)远程屏障?例如,我在网上搜索并发现其他人使用 FlushProcessWriteBuffers 或更改亲和力来将线程绑定到每个内核。这些技巧可以在 Java 中完成吗?

编辑

我想出了一个主意。也许我可以使用 GC 和终结器来实现偏向锁,至少如果那里只有两个线程。不幸的是,慢速路径可能需要显式调用 gc(),这并不实际。

如果 GC 不精确,我可能会陷入死锁。如果 GC 太聪明并在我取消引用之前收集我的对象(也许允许编译器重用堆栈变量,但允许编译器对堆变量做这些事情,忽略获取围栏和加载围栏?),我最终得到了损坏的数据。

编辑

似乎需要一个所谓的“可达性围栏”来防止优化器向上移动对象的最后一个引用。不幸的是,它不在哪里。

【问题讨论】:

  • 我不知道Thread.suspend(),但由于调试器接口的挂起功能只在安全点停止,我会在这里怀疑。
  • 是的,我知道当断点被击中时,线程将处于安全点。 cliffc.org/blog/2015/02/22/…
  • 那么挂起调用是同步的吗?

标签: java suspend barrier


【解决方案1】:

其语义完全由 Javadoc 中指定的内容组成:

暂停此线程。 首先,调用该线程的 checkAccess 方法时不带任何参数。这可能会导致抛出 SecurityException(在当前线程中)。

如果线程处于活动状态,它会被挂起并且不会继续前进,除非它被恢复。

但由于您不打算使用它,因为它已被弃用,所以这一切都无关紧要。

【讨论】:

  • 我知道它已被弃用。
  • 我知道它已被弃用。我不认为它的语义完全由 Javadoc 中指定的内容组成。这个方法的Javadoc是如此的不完整(也就是说,当它说“如果线程处于活动状态,它被挂起”是什么意思?那些“活动”和“挂起”定义在哪里?)。它已被弃用,因为它很容易以错误的方式使用(即它本质上容易死锁),但如果你总是在暂停后立即恢复,为什么它“天生容易死锁”?也许弃用这种方法是合理的,但文档确实是错误的。
猜你喜欢
  • 2022-12-09
  • 1970-01-01
  • 2014-09-25
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多