How to Make a Java Thread Wait for Another Thread's Output

How to make a Java thread wait for another thread's output?

I would really recommend that you go through a tutorial like Sun's Java Concurrency before you commence in the magical world of multithreading.

There are also a number of good books out (google for "Concurrent Programming in Java", "Java Concurrency in Practice".

To get to your answer:

In your code that must wait for the dbThread, you must have something like this:

//do some work
synchronized(objectYouNeedToLockOn){
while (!dbThread.isReady()){
objectYouNeedToLockOn.wait();
}
}
//continue with work after dbThread is ready

In your dbThread's method, you would need to do something like this:

//do db work
synchronized(objectYouNeedToLockOn){
//set ready flag to true (so isReady returns true)
ready = true;
objectYouNeedToLockOn.notifyAll();
}
//end thread run method here

The objectYouNeedToLockOn I'm using in these examples is preferably the object that you need to manipulate concurrently from each thread, or you could create a separate Object for that purpose (I would not recommend making the methods themselves synchronized):

private final Object lock = new Object();
//now use lock in your synchronized blocks

To further your understanding:
There are other (sometimes better) ways to do the above, e.g. with CountdownLatches, etc. Since Java 5 there are a lot of nifty concurrency classes in the java.util.concurrent package and sub-packages. You really need to find material online to get to know concurrency, or get a good book.

Make one thread wait for another to finish

You call join on the thread before it has started. That doesn't work; in that case, join will return immediately, it's not going to wait until the other thread has started and stopped later. You can see this in the API documentation:

Thread.join()

This implementation uses a loop of this.wait calls conditioned on this.isAlive.

Thread.isAlive()

Tests if this thread is alive. A thread is alive if it has been started and has not yet died.

Reorder the statements in your main method

t1.t.start();
t2.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish

edit to answer your questions in the comments:

If you want the thread in AThread to wait for the thread in BThread to finish before doing its job, then you'll need to call join in AThread.run, and change your main method:

class AThread implements Runnable {
Thread t;
Thread threadToWaitFor;

AThread(Thread threadToWaitFor) {
t = new Thread(this);
this.threadToWaitFor = threadToWaitFor;
}

public void run() {
// First wait for the other thread to finish
threadToWaitFor.join();

// ...
}

// ...
}

public class WaitForThread {
public static void main(String[] args) {
BThread t2 = new BThread();
AThread t1 = new AThread(t2.t);

t2.t.start();
t1.t.start();
}
}

How to make a thread wait for a server response

There are multiple concurrency primitives which allow you to implement thread communication. You can use CountDownLatch to accomplish similar result:

public void waitForResponse() {
boolean result = latch.await(10, TimeUnit.SECONDS);
// check result and react correspondingly
}

public void notifyOKCommandReceived() {
latch.countDown();
}

Initialize latch before sending request as follows:

latch = new CountDownLatch(1);

How to make two thread wait for each other outcome?

I like your original approach of using wait / notifyAll to make the Thread doesn't use the CPU until the condition is met for it to resume running. Here's a solution that keeps this approach.

A few notes:

1 - Be careful when synchronizing on a class object. Unless you really want to synchronize the whole class, create an Object and use it as a lock.

2 - Use the volatile keyword to ensure that Java doesn't create a thread local version of the variable and that changes to it's value are instantly reflected to other threads.

public class Threads {
private final Object lock = new Object();
private volatile boolean flag;

class RunnableA implements Runnable {
private volatile boolean condition = false;
@Override
public void run() {
while (true) {
if (condition) {
if (!flag) {
synchronized (lock) {
System.out.println("Setting Flag to True");
flag = true;
lock.notifyAll();
}
}
} else {
System.out.println("Condition is False");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {

}
}
}
}
}

class RunnableB implements Runnable {
@Override
public void run() {
while (true) {
while (flag == false) {
synchronized (lock) {
if (flag == false) {
try {
lock.wait();
} catch (InterruptedException ex) {

}
}
}
}
System.out.println("Kaboom");
}
}
}

public void run() {
RunnableA runnableA = new RunnableA();
RunnableB runnableB = new RunnableB();
Thread t1 = new Thread(runnableA);
Thread t2 = new Thread(runnableB);
t1.start();
t2.start();
try {
Thread.sleep(5000L);
} catch (InterruptedException ex) {

}
runnableA.condition = true;

}
public static void main(String[] args) {
new Threads().run();
}
}

How to make thread wait if prerequisite was not yet done processing and resumes once prerequisite is finished?

I made my implementation simpler.
In my callable object, I do these.

@Override
public String call() throws Exception {
while (!ThreadApp.finishedProcess.containsAll(eodProcess.getPrerequisites())) {
System.out.println(eodProcess.getProcess() + " still waiting for prerequisites...");
Thread.sleep(3000);
}
System.out.println(eodProcess.getProcess() + " working...");
System.out.println(eodProcess.getProcess() + " done!");
ThreadApp.finishedProcess.add(eodProcess.getProcess());
return eodProcess.getProcess();
}

Thank you all for your help!



Related Topics



Leave a reply



Submit