Home > database >  Intended infinite loop not working correctly without content
Intended infinite loop not working correctly without content

Time:02-02

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

  • Related