Halso Johnson
Halso Johnson

Reputation: 75

Write a static synchronized method (wait for a result from thread)

I have a problem with a task. Namely, we must write a class, which is called from Threads. One of the methods is:

public static synchronized void waitForResults() {

}

So the Master-Thread calls this method, and then the Master-Thread triggers an other Thread, that new work is to be done. How can I tell the Master-Thread that he sleep, while the Worker-Thread works?

Upvotes: 1

Views: 1775

Answers (1)

darijan
darijan

Reputation: 9795

Using the wait() and the notify() mechanism. Every java object posses those methods. A mechanism block a thread until some condition is met.

For exampe, if your main thread calls another thread that will change the value of the result variable. Then, you could wait on the result until it gets notified by some other thread:

private static StringBuilder result= new StringBuilder();

public static void mainThreadWork() {
    new WorkerThread().start();
    synchronized (result) {
        System.out.println(result.toString()); //prints ""
        result.wait();
        System.out.println(result.toString()); //prints "modified"
    }
}

private static class WorkerThread extends Thread {
    @Override
    public void run() {
        synchronized(result) {
            result.append("modified");
            result.notify();
        }
    }
}

What happens: when a thread calls a wait on some object, it yields a CPU to other Threads and (as the method name says) waits for another thread to send a notify signal on that thread. notify yields a CPU to the thread that was waiting on that object.

Some rules must be respected, for example, wait() and notify() must be invoked inside a synchronized block.


Since Java 1.5 there are more abstract levels of synchronization and wait-notify mechanisms, so you could check java's concurrent library. It offers you to lock and wait for the object on more abstract object-like level:

private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();

So instead of synchronized blocks and waits and notifies you could just:

public static void mainThreadWork() {
    lock.lock();

    new WorkerThread().start();
    System.out.println(result.toString()); //prints ""
    condition.await();
    System.out.println(result.toString()); //prints "modified"

    lock.unlock();
}

And in the WorkerThread:

@Override
public void run() {
    lock.lock();

    result.append("modified");
    condition.singal();

    lock.unlock();
}

Upvotes: 3

Related Questions