Search code examples
javamultithreadingjava-threads

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?


Solution

  • 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.