gpt4 book ai didi

java - 在不可到达的线程中放置断点强制它运行

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:39:40 26 4
gpt4 key购买 nike

这段代码有一个奇怪的问题:

class Test {
private static boolean test = false;

public static void main(String[] args) {
new Thread(() -> {
while (true) {
if (test) {
System.out.println("Print when breakpoint here!");
test = false;
}
}
}, "Thread1").start();

new Thread(() -> {
while (true) {
System.out.println("Print always");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test = true;
}
}, " Thread2").start();
}
}

如我所料,由于boolean test 不是volatile,Thread1 使用test 的本地缓存值,当Thread2 将其更改为true Thread1 不会做任何事情。但是当我在 System.out.println("Prints when put a breakpoint here!"); 行放置一个断点时,它将到达那里并打印该行!设置断点到底发生了什么?它是否强制程序直接从内存中读取变量的值?还是发生了其他事情?

最佳答案

As I expected, since boolean test is not volatile Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything.

您的期望不正确。

根据 Java 语言规范,如果一个线程更新了一个非 volatile 共享变量,而另一个线程随后在没有适当同步的情况下读取它,那么第二个线程可能看到新值,或者它可能看到较早的值。

所以您所看到的是 JLS 允许的。


实际上,当调试代理附加到 JVM 时,它通常会导致 JIT 编译器以较低的优化级别重新编译部分或所有方法……甚至可能使用字节码解释器执行它们。对于在其中设置了断点的方法以及单步执行1 时,很可能会发生这种情况。这可能会导致在调试时使用共享变量但未正确同步的代码出现不同的行为

这也是同步不充分导致调试困难的原因之一。


As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

这就是调试 C/C++ 时发生的情况。没有指定 JVM 如何处理这个问题,但典型的 JVM 有其他选项来实现断点......因为字节码和 JIT 编译。


When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep?

sleep 会导致当前线程挂起。在实现级别发生的事情未指定。但是, native 线程机制可能会将挂起线程的所有未完成写入(即脏缓存条目)刷新到内存中......作为执行线程上下文切换过程的一部分。

同样,如果您使用 print 语句,典型的 I/O 堆栈具有内部同步,可以触发缓存刷新等。这也可以改变您尝试调试的代码的行为。

但是,我要强调的是,这些行为并未指定。


1 - 允许 JIT 优化器重新排序分配,前提是这不会改变单线程行为。但是,如果您正在调试一个方法并观察变量的值,则重新排序的效果是可见的(对程序员而言)。去优化/解释避免了这种情况。幸运的是,现代 JVM/调试代理可以根据需要“即时”执行此操作。

关于java - 在不可到达的线程中放置断点强制它运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53964510/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com