javamultithreading

How would I have a thread wait on a lambda?


This is my first time messing with threads. The project takes user input with a lambda, so I need to wait until that lambda gets valid data to resume the thread. From my research I haven't found a good way to do that other than while (var == null) {} which doesn't seem ideal.

An example that hopefully shows what I want to do is: (I need to set a variable in a lambda that depends on user input, so it won't be run right away, and I need the thread to wait until the variable is set)

public class MRE {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        InputHandler[] handler = new InputHandler[1];
        Thread thread = new Thread(() -> {
            Object wait = new Object();
            boolean[] matches = new boolean[1];
            synchronized (wait) {
                handler[0] = (message) -> {
                    matches[0] = message.equals("true");
                    wait.notify();
                };
                try {
                    wait.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //the thread needs the boolean to be set for whatever it does next
        });
        thread.start();
        while (scanner.hasNext()) {
            handler[0].handleMessage(scanner.nextLine());
        }
    }

    interface InputHandler {
        void handleMessage(String message);
    }
}

Solution

  • I got an answer from a java discord, what I need here is a CountDownLatch. Here's how it would work in my code:

    public class MRE {
        InputHandler handler = (message) -> {};
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            Thread thread = new Thread(() -> {
                boolean[] matches = new boolean[1];
                CountDownLatch latch = new CountDownLatch(1);
                setHandler((message) -> {
                    matches[0] = message.equals("true");
                    latch.countDown();
                    setHandler((message) -> {});
                });
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
            thread.start();
            while (scanner.hasNext()) {
                handler.handleMessage(scanner.nextLine());
            }
        }
    
        private void setHandler(InputHandler newHandler) {
            handler = newHandler;
        }
    
        interface InputHandler {
            void handleMessage(String message);
        }
    }