There is a View:

public class View { public volatile String s; public void viewer() { JFrame frame = new JFrame(); JTextField t = new JTextField(); frame.add(BorderLayout.NORTH, t); frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.setVisible(true); t.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { s = t.getText(); } }); } 

There is a controller:

 public class Main { public static void main(String[] args) throws InterruptedException { View view = new View(); view.viewer(); //Thread.sleep(20000); //while (view.s == null); System.out.println("smth"); } } 

How to put a stream to sleep until an event occurred in View (until all the fields were filled out)?
I commented on my two options. The first one falls asleep only for a fixed time and, accordingly, is not connected in any way with the event. The second while works fine, but it looks somehow wrong.
What is a more competent way, without loading the system with an unnecessary loop?

  • one
    I don’t know whether it is worth "lull" the thread just in the actionPerformed add some sort of callback ? - JVic
  • I do not understand how? By the type of check flag to add? So how then in the execution of the controller to suspend the flag? Or are you not about that? - faq700
  • are you trying to implement MVC? - Mikhail Vaysman
  • @ faq700 No, I'm talking about the function that will be called on the actionPerformed event after s = t.getText(); your function will be fulfilled - JVic
  • I haven't done anything with Java for a long time, but it seems to me that you can look at conditions - avp

3 answers 3

In your case, you can use java.util.concurrent.BlockingQueue .

In one thread, you add an item to the queue. From another you are trying to get it, but if the queue is empty, then the thread is blocked waiting for the element to appear.

 final BlockingQueue<String> queue = new ArrayBlockingQueue<>(1); //где то в коде //поток будет ждать String value = queue.take(); //где то в другом потоке queue.add("hello"); 
  • Thanks, this is a really easy way to solve the problem! It remains to understand the essence))) - faq700

You need to use the wait() and notify() / notifyAll() .

Example:

 synchronized (objectForBlock) { <...> objectForBlock.wait(); // усыпит поток этот выполнения <...> } 

When you need to wake up a thread, call objectForBlock.notifyAll() This will wake up all threads blocked by objectForBlock

  • Do not forget that random spurious wakeups possible - spurious wakeups . So the code is not entirely correct. It is required to call wait to wrap the loop, and in it to check the wake - up condition - Artem Konovalov
  • As I understand it, wait () and notify () / notifyAll () do not work in the static method (. Just did not understand why - faq700

As far as I understand the task, CountDownLatch will do . I also discovered some time ago a good little article that can help. She is here . There are some ways with streams.

  • It makes sense to give in the answer an example of how CountDownLatch works in this case. - Regent
  • Thanks for the advice! I will try to understand the design proposed by you. It is a pity there is no example)) - faq700