Search code examples
javaconditional-statementswaitjoptionpanethread-sleep

Stop code until a condition is met


How can you create a function or component etc that will stop all running code until a condition is met?

For example the same way as a JOptionPane will do, if I have this for example:

JOptionPane.showInputDialog(null, "Hello", "Title", 1);

Within a function etc and then print to the console afterwards it it will not print until I close the JOptionPane.

I am guessing this component has some sort of thread setup built in to do this but how could I duplicate that with my own functions?

So say for example I wanted to make JFrames delay everything until it was closed so it acts like a JOptionPane.

Or for example have a function that had multiple inputs which got updated and inside it did some maths with those and if it was a certain value returned a boolean, but then everything else but those was paused until the true boolean was returned.

I am guessing the solution is some sort of thread setup but I am quite new to Java and when I have coded in the past I have not really used threads so I cannot create a good stop-start/pause-run style function system yet.

Does anyone have any suggestions how to achieve this or better yet code examples showing this type of thing working?


Solution

  • You create a monitor (which is just a simple Object)

    public static final Object monitor = new Object();
    public static boolean monitorState = false;
    

    Now you create a wait method

    public static void waitForThread() {
      monitorState = true;
      while (monitorState) {
        synchronized (monitor) {
          try {
            monitor.wait(); // wait until notified
          } catch (Exception e) {}
        }
      }
    }
    

    and a method to unlock your waiters.

    public static void unlockWaiter() {
      synchronized (monitor) {
        monitorState = false;
        monitor.notifyAll(); // unlock again
      }
    }
    

    So when you want to do something fancy, you can do it like this:

    new Thread(new Runnable() {
      @Override
      public void run() {
        // do your fancy calculations
        unlockWaiter();
      }
    }).start();
    
    // do some stuff    
    waitForThread();    
    // do some stuff that is dependent on the results of the thread
    

    Of course, there are many possibilities, this is only one version of how to do it.