gpt4 book ai didi

java - Java中的线程间通信

转载 作者:行者123 更新时间:2023-11-29 04:40:40 25 4
gpt4 key购买 nike

为什么在下面的 Java 代码中:

public class WaitForOther {

private volatile boolean in = false;// need volatile for transitive closure
// to occur



public void stoppingViaMonitorWait() throws Exception {

final Object monitor = new Object();

new Thread(new Runnable() {

@Override
public void run() {
synchronized (monitor) {
in = true;
try {
monitor.wait(); // this releases monitor
//Thread.sleep(8000); //No-op
System.out.println("Resumed in "
+ Thread.currentThread().getName());

} catch (InterruptedException ignore) {/**/
}
}

}
}).start();

System.out.println("Ready!");
while (!in); // spin lock / busy waiting
System.out.println("Set!");
synchronized (monitor) {
System.out.println("Go!");
monitor.notifyAll();
}

}

取消注释 Thread.sleep(8000);//No-op 导致缩短的输出:

准备好了!
放!
去吧!

否则会在中断的线程 0 中正确恢复:

Ready!
Set!
Go!
Resumed in Thread-0

这是调用上述行为的 JUnit 测试,正如评论中所要求的那样:

public class WaitForOtherTest {

WaitForOther cut = new WaitForOther();


@Test
public void testStoppingViaMonitorWait() throws Exception {
cut.stoppingViaMonitorWait();
}



}

谢谢!

最佳答案

我已经在 J​​Unit 中尝试过您的测试,但我得到的结果与您的体验相反:

  1. Thread.sleep 被注释掉时,测试运行正常并打印“Resumed in <>”
  2. Thread.sleep 在代码中(实际执行)时,JVM 终止并且“Resumed in ...”打印。

原因是 JUnit 在测试完成时终止了 VM。它执行 System.exit();。您很幸运在案例 1 中获得了完整的输出,因为它是在单独的线程中打印的,并且 JUnit 不会等待该线程。

如果要确保线程在测试方法结束之前完成,要么需要让 API 等待线程,要么需要让测试等待线程。

如果您的stoppingViaMonitorWait 方法返回它创建的线程,您可以在测试中等待。

@Test
public void testStoppingViaMonitorWait() throws Exception {
Thread x = cut.stoppingViaMonitorWait();
x.join();
}

另一种选择是将一个线程池(ExecutorService 的一个实例)注入(inject)到您正在测试的类中,让它在池中安排它的线程(这在任何情况下都更好),在您的测试方法中,您可以调用 ExecutorService.awaitTermination

关于java - Java中的线程间通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39322831/

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