Thread.sleep() 和断点之间的区别(暂停线程)
Posted
技术标签:
【中文标题】Thread.sleep() 和断点之间的区别(暂停线程)【英文标题】:Difference between Thread.sleep() and breakpoint (Suspend Thread) 【发布时间】:2014-12-11 18:19:37 【问题描述】:我正在解决我们的 ArcGIS 地图实现中的一个奇怪错误。最近,我注意到当我在某个位置放置断点并在调试模式下运行应用程序时,我们的软件可以正常工作(可能我们面临并发/线程问题)。命中断点后,我立即(1-2 秒)恢复应用程序,地图上的所有内容都完美绘制。 但是,当我用 Thread.sleep(2000); 替换断点时;并运行应用程序,错误仍然存在。
对我来说这真的很奇怪,我认为这两件事会完全一样。断点设置为“Suspend Thread”,我使用 Eclipse IDE。
Java 中让线程休眠和挂起线程有什么区别?
编辑: 我不要求这个特定的错误解决方案。我只是想知道这两种情况下程序的执行有什么区别:
案例一
-
打开 Eclipse IDE
在 X 行设置断点
调试为...我的程序
ButtonEvent,程序在第 X 行遇到断点
我点击 Eclipse 中的恢复按钮
案例 2
-
打开 Eclipse IDE
将 Thread.sleep(2000) 放在 X 行的最开始
调试为...我的程序
按钮事件
在这里粘贴代码不会有任何区别,因为我没有询问任何特定的代码执行场景,我只是感兴趣 JVM 是否以与处理 Thread.sleep() 相同的方式处理断点。 当线程在特定时间休眠时,JVM 会发生什么?当线程被挂起(通过命中断点)时,JVM 中发生了什么?有什么区别吗?
【问题讨论】:
我们没有看到任何代码。这个问题太笼统了,没有任何信息。请添加您的代码,以便我们了解您的错误 没有要附加的代码。示例会很复杂,生产 SSCCE 可能需要大约一个月的时间。我严格询问 Thread.sleep() 和断点中的差异 如果没有代码,就没有答案... Thread.sleep 使线程进入睡眠状态。断点会暂停所有到达它的线程。 这不仅仅是关于 sleep() 与断点的关系。您应该问,在调试器中运行程序和正常运行程序有什么区别(无论“正常”是什么意思)。您是否在调试器中使用 sleep() 调用而不是断点进行了尝试?我不知道您通常如何运行程序,也不知道您的 Eclipse 是如何设置的,而且我对 Java 调试器也不太了解;所以据我所知,当你在调试器中运行时,它可能是一个完全不同的 JVM。 如果你的程序是正确的,不同的 JVM 应该不会有什么不同,但如果你的程序有并发错误,它可能会产生很大的不同。 【参考方案1】:有一些相当大的差异,是的。
Thread.sleep 请求操作系统将线程从 CPU 调度中移除 n 毫秒。请注意,此影响是特定于操作系统的,并且主要限于一个线程。
进入断点需要激活 JVM 的调试模式,这会影响整个 JVM 的行为,从而影响计时/竞争。 AMD 有documented the performance effects of putting the JVM into debug mode。效果确实各不相同,其中很多都影响了 JVM 和调试器之间的通信,并限制了 JVM 在调试模式下允许进行的优化。最极端的例子是不让 JVM 对某些方法使用本机字节码,从而迫使它使用慢得多的解释器。然而,从这个问题的角度来看,最重要的区别是调试器提供了停止单个线程或多个线程的能力。
请求进入睡眠状态的线程与导致另一个线程阻塞的线程之间存在很大差异。在 Java 中,它需要线程之间的协作来停止一个线程,即使是一个断点。在断点的情况下,JVM 为我们完成了协作,并且仅在线程到达安全点时才会发生。安全点不会出现在每一行代码中,因此会非常强烈地影响竞争条件,因为 JVM 必须等待线程到达安全点,然后才能停止它并由调试器接管。安全点通常发生在方法调用和循环的后边缘(但并非总是如此)。
【讨论】:
【参考方案2】:我认为挂起将迫使您使用Thread.resume()
重新激活Thread
,而如果使用Thread.sleep()
,则不必这样做。
来自 API,关于 resume()
:“此方法将线程置于挂起状态,可以使用 resume()
方法恢复。”
睡眠只会停止它,但您不必再次激活它。
希望对你有帮助。
【讨论】:
以上是关于Thread.sleep() 和断点之间的区别(暂停线程)的主要内容,如果未能解决你的问题,请参考以下文章
Thread.Sleep() 和 await Task.Delay 之间的真正区别是啥? [复制]
Windows 服务卡在“启动”状态以及 Thread.Sleep() 和 Task.Delay() 之间的区别
C# Task.Delay()和Thread.Sleep()有什么区别?