#How would I have a thread wait on a lambda?

54 messages · Page 1 of 1 (latest)

earnest crane
#

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 havent found a good way to do that other than while (var == null) {} which doesn't seem ideal.

blissful moatBOT
#

This post has been reserved for your question.

Hey @earnest crane! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

serene wing
#

what input are you taking?

earnest crane
#

Right now just a string from terminal, but thats for testing.

serene wing
#

well what do you mean by valid data?

earnest crane
#

oh it needs to be one of three strings(selecting an option)

#

specifically im looking for one of "draft", "set", or "random"

serene wing
#

why don't you just check if the input is equal to one of those things ?

earnest crane
#

because I can't stop the main thread until the user gives input(This is eventally going to be server side code on something with multiple users)

serene wing
#

so let me see if I got this right

#

you have a main thread which shouldn't stop running so you have delegated the user input to another thread and you are now wondering how to notify the main thread when valid input has been provided?

earnest crane
#

no, user input is handled on the main thread. I'm passing the thing that handles user input a lambda to run the message through and I want to continue the side thread when that lambda has gotten valid input

serene wing
#

you just said you can't stop the main thread until the user gives input

earnest crane
#

I'm not

serene wing
#

can the main thread block or can it not block?

earnest crane
#

the main thread is getting a lambda that extends a specific interface for it to run messages through

#

as a simplified example: ```java
SelectionType type;
//runner handles the user input
runner.captureMessagesFrom(user, (message) -> {
switch (message.toLowerCase()) {
case "draft" -> type = SelectionType.DRAFT;
case "set" -> type = SelectionType.SET;
case "random" -> type = SelectionType.RANDOM;
default -> return false;
}
return true;
}
//use type for something

serene wing
#

who runs this function?

#

is it the main thread or some other thread

earnest crane
#

its run on the main thread when it gets a message

#

and it gets the message from side threads that are actually doing the listening for user input

serene wing
#

right so what is the problem with validating the input before sending the message off to the main thread?

earnest crane
#

the problem is I need to know that type is not null before the code continues, and that requires the specific user to send a valid message.

#

the main thread can't just wait forever because then we wouldnt handle messages from other users

#

so I need the code to wait until the value is set, and I'm not sure how to do that

serene wing
#

this is confusing

earnest crane
serene wing
#

in the first place you can't set type from inside the lambda

earnest crane
serene wing
#

how does the main thread handle this message?

#

Is it running an event loop?

#

like run me through what happens when some thread receives some data from somewhere

#

why can't it validate that data before sending it off to the main thread

earnest crane
serene wing
#

so im assuming the main thread is ran by this api then?

#

again, what is the problem with validating the input in the current thread before captureMessageFrom

#

wait a second

serene wing
#

in other words:

SelectionType type;
//runner handles the user input
runner.captureMessagesFrom(user, (message) -> {
    switch (message.toLowerCase()) {
        case "draft" -> type = SelectionType.DRAFT;
        case "set" -> type = SelectionType.SET;
        case "random" -> type = SelectionType.RANDOM;
        default -> return false;
    }
    return true;
}
//wait until type !=null
//use type for something
#

is this what you are trying to do?

earnest crane
earnest crane
serene wing
#

okay

#

you can do this multiple ways

#

the simplest is with a CountDownLatch

#
        SelectionType type;
        final CountDownLatch latch = new CountDownLatch(1);

        runner.captureMessagesFrom(user, (message) -> {
            try{
                switch (message.toLowerCase()) {
                    case "draft" -> type = SelectionType.DRAFT;
                    case "set" -> type = SelectionType.SET;
                    case "random" -> type = SelectionType.RANDOM;
                    default -> return false;
                }
                return true;                
            }finally {
                latch.countDown();
            }

        });
        try {
            latch.await();
        } catch (InterruptedException e) {
            //handle interrupt as you see fit
        }

//use type for something
#

the thread will block on await() until another calls countDown()

#

I suggest before jumping into multi-threaded code to have a look at synchronization blocks, locks and atomic variables

#

it's also important to keep in mind that depending on your code the thread on await() might block indefinitely if the main thread shuts down before processing the message

serene wing
earnest crane
#

Thank you, this worked!

blissful moatBOT
# earnest crane Thank you, this worked!

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.