奇怪的Java问题,而循环终止

时间:2011-03-13 03:46:08

标签: java termination

我有一段看起来像这样的代码:

Algorithm a = null;  
while(a == null)  
{  
    a = grid.getAlgorithm();  
}  
我的Grid类中的

getAlgorithm()返回一些Algorithm的子类型,具体取决于用户从某些选项中选择的内容。

我的问题是,即使选择了算法,循环也永远不会终止。但是,如果我只是放置一个System.out.println(“得到这里”),那就不是那么棘手了。在调用getAlgorithm()之后,程序运行得非常好,循环按预期终止。

我的问题是:为什么添加魔术打印语句突然使循环终止?

此外,当我开始使用我的新笔记本电脑时,这个问题首先出现了,我怀疑这是相关的,但我认为值得一提。

编辑:有问题的程序不是多线程的。 getAlgorithm()的代码是:

public Algorithm getAlgorithm ()  
{  
    return algorithm;  
}

其中算法最初为null,但会在某些用户输入时更改值。

5 个答案:

答案 0 :(得分:2)

我认为问题必须处理grid.getAlgorithm的执行方式。如果执行该方法的成本非常低,那么只要该方法继续返回null,您的while循环就会非常快地循环。这通常被称为busy wait

现在听起来您的新笔记本电脑遇到starvation问题,而这个问题并未在您的旧电脑上显示。很难说为什么,但如果你看一下我上面提到的链接,维基百科的文章确实表明繁忙的等待确实有不可预测的行为。也许您的旧计算机比新笔记本电脑更好地处理用户IO。无论如何,在您的新笔记本电脑上,该循环正在从处理您的用户IO的任何资源中获取资源,因此它正在使负责打破循环的过程匮乏。

答案 1 :(得分:1)

您正在进行有效的投票。这是一种不好的做法。你应该至少让轮询线程休眠(使用Thread.sleep)。由于println做了一些io,它可能就是这样。如果您的应用程序不是多线程的,则根本不可能正常工作。

答案 2 :(得分:1)

如果此循环是等待GUI中的用户输入然后哎哟。糟糕,糟糕的想法,甚至加上Thread.sleep()我都不会推荐它。相反,您很可能希望在相关组件上注册事件侦听器,并且仅在内容更改时触发验证代码。

很可能你的程序锁定了,因为你已经达到了某种形式的死锁,尤其是如果你的应用程序是多线程的。我并没有试图解决这个问题并且破解你的方式,而是认真考虑重新设计这部分应用程序的工作原理。

答案 3 :(得分:0)

你应该检查getAlgorithm(),方法中一定有问题。

答案 4 :(得分:0)

有两种情况:

  1. 您的代码实际上并不是多线程的。在这种情况下,您需要在循环中插入某种用户输入。否则你不妨把它留作算法a = grid.getAlgorithm();并防止无限循环。
  2. 您的代码是多线程的,在这种情况下,您会遇到某种“可见性”问题。转到Atomicity, Visibility and Ordering或阅读Java Concurrency in Practice以了解有关可见性的更多信息。本质上,这意味着如果线程之间没有某种同步,那么您循环的线程可能永远不会发现由于JVM可能执行的优化而导致值发生了变化。
  3. 您没有提及有关此代码运行方式的任何上下文。如果它是基于控制台的应用程序,并且您从“main”函数启动,您将知道是否存在多线程。我假设情况并非如此,因为你说没有多线程。另一个选择是这是一个swing应用程序,在这种情况下你应该阅读Multithreaded Swing Applications。它可能是一个Web应用程序,在这种情况下,类似于swing的情况可能适用。

    在任何情况下,您总是可以调试应用程序以查看哪个线程正在写入'algorithm'变量,然后查看从哪个线程读取它。

    我希望这会有所帮助。在任何情况下,如果您在问题中提供更多上下文,您可能会找到更多帮助。特别是对于一个有趣的标题,如'奇怪的Java问题,而循环终止'。