SYOB SYOT
SYOB SYOT

Reputation: 1190

How to enable thread in java to receive notifications from 2 threads?

I am writing program which has multiple threads. inside that program i often use wait and notify to make one thread wait until other one wakes it up.

in my imaginary project, lets say i have 3 threads: m, a and b. m is the main. m thread starts a thread and starts b thread. m thread should wait for some thread to complete with its job (not to die). if a completes, m should be waken and do one thing. if b completes, it should be waken and do another thing.

i could use something like this in m:

synchronized(a)
{
    a.wait();
}

and something like this in a:

synchronized(this)
{
    notify();
}

the same thing goes if i want to wait for b. in m:

synchronized(b)
{
    b.wait();
}

in b:

synchronized(this)
{
    notify();
}

but, if i want to wait for both of them, i would need code like this:

synchronized(a, b)
{
    a,b.wait();
}

but of course, this is not supported in java.

of course, i could put main to sleep(32) or something like that, and put done flags in a and b, and when m wakes up, it would check the flags, and know which one of them finished. but with the wait-notify approach i wanted to avoid constantly checking those done flags in a and b.

so, what is a solution? is there any way, i could found out that a or b finished (not died) from m except constantly checking the flags?

Upvotes: 0

Views: 279

Answers (4)

Esko
Esko

Reputation: 29367

To have main thread m react after any of the child threads (in this case a and b) finishes working there's a few options.

At its simplest, m should hold the dependent threads in a list and in two loops first start the other threads and then after that in another loop wait for the thread to finish. So, you need to have something like this:

public class MainThread {
    public void run() {
        List<Thread> threads = Arrays.asList(
            new Thread(() -> react(this)),
            new Thread(() -> react(this)),
        );
        // start all threads first to avoid deadlock
        threads.forEach(Thread::start);
        // wait for all threads to finish in order
        threads.forEach(Thread::join);
        // here you can do whatever post steps you want
    }
    public void react(Thread t) {
        System.out.print("MainThread called by " + t);
    }
}

There's a lot of other solutions available to achieve something like this:

and so on and on.

Upvotes: 1

sohan
sohan

Reputation: 597

In your context using CompletableFuture will serve the purpose.

Upvotes: 0

john16384
john16384

Reputation: 8044

Instead of having m do things when a or b complete, just have a and b do the right thing.

I would suggest doing this with CompletableFuture:

CompletableFuture.runAsync( <thread A> )
     .thenRun( <stuff that should be done after A completes> );

Upvotes: 1

Niklas P
Niklas P

Reputation: 3507

You can do the synchronisation (wait, notify) on a shared object. Maybe on m?!

Upvotes: 1

Related Questions