开发者

Weird Java problem, while loop termination

开发者 https://www.devze.com 2023-02-16 17:09 出处:网络
I have a piece of code that looks like this: Algorithm a = null; while(a == null) { a = grid.getAlgorithm();

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 an开发者_如何学编程d 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.


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.


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.


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.


You should check getAlgorithm(), there must be something wrong in the method.


There are two scenarios:

  1. Your code is really not meant to be multi-threaded. In this case you need to insert some sort of user input in the loop. Otherwise you might as well leave it as Algorithm a = grid.getAlgorithm(); and prevent the infinite loop.
  2. Your code is multi-threaded in which case you have some sort of 'visibility' problem. Go to Atomicity, Visibility and Ordering or read Java Concurrency in Practice to learn more about visibility. Essentially it means that without some sort of synchronization between threads, the thread you are looping in may never find out that the value has changed due to optimizations the JVM may perform.

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'.

0

精彩评论

暂无评论...
验证码 换一张
取 消