为什么Java在到达无限循环时挂起主线程?

时间:2015-03-25 20:38:00

标签: java multithreading swing

我的代码有一个更新布尔变量的UI线程。我遇到的问题是,当变量变为真时,我希望主程序继续执行。

public static void main(String[] args) throws Exception{
//Display the UI by creating an instance of Node
Node node = new Node();

//Wait for the node to connect to a router before continuing
while(!isConnectedToRouter);

//Do other things
}

调试时我注意到主线程自行挂起,所以main永远不会进入"做其他事情"。即使在另一个线程使布尔值isConnectedToRouter成为真。如果我将while循环更改为

//Wait for the node to connect to a router before continuing
while(!isConnectedToRouter){
    Thread.sleep(1);
}

它有效,但它让我意识到我做错了什么。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

比忙碌的等待更好的是在主线程中睡觉,直到有时间继续。

java.util.concurrent具有高级别的线程接口,更易于安全使用并适合大多数情况。

例如,使用CountDownLatch等待可以完成:

CountDownLatch latch = new CountDownLatch(1);

,此对象应该在主线程和工作者中都可见。需要使用相同的对象进行锁定。

等待主线程:

latch.await();

当另一个线程准备就绪时:

latch.countDown();

此实现的优势在于,您无需担心在等待阶段开始之前工作线程已准备好的情况。在那种情况下,await()做正确的事并立即返回。

在这种情况下,也可以使用来自Object的旧的低级方法,但是需要特别小心来处理工作线程在主线程等待之前就绪的情况 - 而不检查它是否会很容易锁定主线程。所以我建议坚持java.util.concurrent,除非你有充分的理由不这样做。这些类的存在是为了帮助编写安全的线程代码。

注意:为简洁起见,我省略了代码处理InterruptedExceptions - 这应该与latch.wait()Object.wait()

一起完成

答案 1 :(得分:0)

你应该使布尔波动,以便主线程可以读取该布尔变量的最新值,而不是只读取寄存器中的值。