奇怪的Java问题,while循环终止
我有一段代码,如下所示:
Algorithm a = null;
while(a == null)
{
a = grid.getAlgorithm();
}
我的 Grid 类中的 getAlgorithm() 返回一些算法子类型,具体取决于用户从某些选项中选择的内容。
我的问题是,即使选择了算法后,循环也永远不会终止。然而,如果我简单地放置一个 System.out.println("Got here"); ,这并不是棘手的问题。在我调用 getAlgorithm() 之后,程序运行得非常好并且循环按预期终止。
我的问题是:为什么添加魔术打印语句会突然使循环终止?
此外,当我开始使用我的新笔记本电脑时,这个问题第一次出现,我怀疑这是否相关,但我认为值得一提。
编辑:有问题的程序不是多线程的。 getAlgorithm() 的代码是:
public Algorithm getAlgorithm ()
{
return algorithm;
}
其中算法最初为空,但会根据某些用户输入更改值。
I have a piece of code that looks like this:
Algorithm a = null;
while(a == null)
{
a = grid.getAlgorithm();
}
getAlgorithm() in my Grid class returns some subtype of Algorithm depending on what the user chooses from some options.
My problem is that even after an algorithm is selected, the loop never terminates. However, that's not the tricky bit, if I simply place a System.out.println("Got here"); after my call to getAlgorithm(), the program runs perfectly fine and the loop terminates as intended.
My question is: why does adding that magic print statement suddenly make the loop terminate?
Moreover, this issue first came up when I started using my new laptop, I doubt that's related, but I figured it would be worth mentioning.
Edit: The program in question is NOT multithreaded. The code for getAlgorithm() is:
public Algorithm getAlgorithm ()
{
return algorithm;
}
Where algorithm is initially null, but will change value upon some user input.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我相信问题必须处理 grid.getAlgorithm 的执行方式。如果执行该方法的成本非常小,那么只要该方法继续返回 null,您的 while 循环就会非常快地循环。这通常称为忙等待。
现在,您的新笔记本电脑似乎遇到了 饥饿 问题,而您的旧计算机上并未出现该问题。很难说为什么,但如果您查看我上面包含的链接,维基百科文章确实表明繁忙等待确实具有不可预测的行为。也许您的旧计算机比新笔记本电脑能更好地处理用户 IO。无论如何,在您的新笔记本电脑上,该循环会从处理用户 IO 的任何内容中夺走资源,因此它会导致负责打破循环的进程处于饥饿状态。
I believe the issue has to deal with how grid.getAlgorithm is executed. If there is very little cost associated with executing the method, then your while loop will cycle very quickly as long the method continues to return null. That is often referred to as a busy wait.
Now it sounds like your new laptop is encountering a starvation issue which didn't manifest on your old computer. It is hard to say why but if you look at the link I included above, the Wikipedia article does indicate that busy waits do have unpredictable behavior. Maybe your old computer handles user IO better than your new laptop. Regardless, on your new laptop, that loop is taking resources away from whatever is handling your user IO hence it is starving the process that is responsible for breaking the loop.
您正在进行主动轮询。这是一个不好的做法。您至少应该让轮询线程休眠(使用 Thread.sleep)。由于 println 执行一些 io 操作,因此它可能就是这样做的。如果您的应用程序不是多线程的,它根本不可能工作。
You are doing active polling. This is a bad practice. You should at least let the polling thread sleep (with Thread.sleep). Since println does some io, it probably does just that. If your app is not multithreaded it is unlikely to work at all.
如果这个循环是为了等待 GUI 中的用户输入,那么哎呀。坏主意,坏主意,即使添加了 Thread.sleep() ,我也不会推荐它。相反,您很可能希望在相关组件上注册一个事件侦听器,并且仅在内容更改时才触发验证代码。
您的程序很可能被锁定,因为您已经达到某种形式的死锁,特别是如果您的应用程序是多线程的。我不会尝试解决这个问题并解决它,而是认真考虑重新设计应用程序的这一部分的工作方式。
If this loop is to wait for user input in a GUI then ouch. Bad, bad idea and even with
Thread.sleep()
added I'd never recommend it. Instead, you most likely want to register an event listener on the component in question, and only have the validation code fire off when the contents change.It's more than likely you're program is locking up because you've reached some form of deadlock more than anything else, especially if your application is multithreaded. Rather than try to solve this issue and hack your way round it, I'd seriously consider redesigning how this part of the application works.
你应该检查getAlgorithm(),该方法一定有问题。
You should check getAlgorithm(), there must be something wrong in the method.
有两种情况:
您没有提及有关此代码如何运行的任何上下文。如果它是基于控制台的应用程序并且您从“主”函数开始,您就会知道是否存在多线程。我假设情况并非如此,因为你说没有多线程。另一种选择是这是一个 swing 应用程序,在这种情况下,您应该阅读 多线程 Swing 应用程序。它可能是一个 Web 应用程序,在这种情况下,可能会应用与 swing 类似的情况。
在任何情况下,您始终可以调试应用程序以查看哪个线程正在写入“算法”变量,然后查看哪个线程正在从中读取。
我希望这有帮助。无论如何,如果您在问题中提供更多背景信息,您可能会找到更多帮助。特别是对于标题为“怪异的 Java 问题,while 循环终止”这样一个有趣的问题。
There are two scenarios:
You did not mention any context around how this code is run. If it is a console based application and you started from a 'main' function, you would know if there was multi-threading. I am assuming this is not the case since you say there is no multithreading. Another option would be that this is a swing application in which case you should read Multithreaded Swing Applications. It might be a web application in which case a similar case to swing might apply.
In any case you could always debug the application to see which thread is writing to the 'algorithm' variable, then see which thread is reading from it.
I hope this is helpful. In any case, you may find more help if you give a little more context in your question. Especially for a question with such an intriguing title as 'Weird Java problem, while loop termination'.