I want to have a while loop interupt a program until some specific condition is met. The condition will be met, even if the program is stuck in the loop. (Via a button actionlistener)
This is my current code:
boolean buttonPressed = false; while (!buttonPressed) { } // Infinite loop intended buttonPressed = false;
buttonPressed will be set to true at some specific Point (via a button). I cannot get it to work like this without having content inside my loop.
Edit: Especially weird is that it works when i put a system.out statement into the loop
CodePudding user response:
What you have created is a 'spin loop'. This is very bad. The computer will slow down to a crawl, and you will be burning through the battery of the device it is running on. The fans will turn on. It's a mess.
Your entire setup is wrong. You don't repeatedly check a condition until it is met, that's just not a proper way to communicate between threads.
Instead, whatever is setting buttonPressed
to true should also send a signal, waking up whatever is waiting until the button is pressed.
So why doesn't it work?
Reasons - when you spin loop, weird things happen. The CPU is spending all its resources endlessly running your spinloop and doesn't get around to running anything else.
So how should it be done
Depends on what is happening here, but, here is one trivial example:
private class GatedButton {
private int count = 0;
private final Object lock = new Object[0];
public void pressButton() {
synchronized (lock) {
count ;
lock.notifyAll();
}
}
public void waitUntilPress() {
try {
synchronized (lock) {
int currentVal = count;
while (currentVal == count) lock.wait();
}
} catch (InterruptedException e) {
throw new RuntimeException("Wait until press interrupted");
}
}
}
This is code 'safe' and will cause the CPU to sleep without wasting a ton of energy or resources. The magic of wait()
at work.
Alternatives
You can use a CountdownLatch
or perhaps you're looking for concurrent queue - the java.util.concurrent
package has all sorts of useful abstractions for this sort of thing.
But Thread.sleep(1)
works fine for me
Check your activity monitor for the epic amounts of battery that wastes. It's not 'fine'.
CodePudding user response:
while (!buttonPressed) {Thread.sleep(1);} worked perfectly for me