Tuesday, September 16, 2008

A great Thread example from Nikos Pugunias(http://nikojava.wordpress.com/)

Hi Zhou!
You should be 100% certain that wait() is a method of Object.Consider 2 threads: Thread A carries out a loooong task. Thread B must wait for A's result to go on with its job.This trick between threads happens with a single object that both threads can access: a token. it's like the piece of wood that the athletes running 4x100m in the Olympics: Runner 1 starts, Runner 2 waits for the token from Runner 1, as soon as he gets it Runner 2 starts and so on...

//Here's the first runner,
class Runner1 extends Thread { }

//that holds a wooden stick.

class Runner1 extends Thread {
Object stick;
public Runner1(Object stick) { this.stick = stick; }
}


//This runner has a loooong task to do,

class Runner1 extends Thread {
Object stick;
public Runner1(Object stick) { this.stick = stick; }
public void run() { // perform a loooooong task here }
}


//and then he will give the token to another runner.

class Runner1 extends Thread {
Object stick;
public Runner1(Object stick) { this.stick = stick; }
public void run() {
synchronized (stick) {
// perform a loooooong task here stick.notify();
}
}
}



//Here's the second runner
class Runner2 extends Thread { }

//that can also receive a wooden stick.

class Runner2 extends Thread {
Object stick;
public Runner2(Object stick) { this.stick = stick; }
}



//This second runner has also something to do,

class Runner2 extends Thread {
Object stick;
public Runner2(Object stick) { this.stick = stick; }
public void run() {
// I want to do something after
// the first runner has finished.
}
}



// but he'll have to wait for the token first.

class Runner2 extends Thread {
Object stick;
public Runner2(Object stick) { this.stick = stick; }
public void run() {
// wait for Runner1
synchronized (stick) {
try { stick.wait();
} catch (InterruptedException e) { }
}
// I want to do something
//after the first runner has finished.
}
}



//+++++++++++++++++++++++++++
//Here's the complete code.
//+++++++++++++++++++++++++++

public class Run {
public static void main(String[] args) {
Object token = new Object();
new Runner1(token).start();
new Runner2(token).start();
}
}

class Runner1 extends Thread {
Object stick;
public Runner1(Object stick) { this.stick = stick; }
public void run() {
synchronized (stick) {
// perform a loooooong task here stick.notify();
}
}
}

class Runner2 extends Thread {
Object stick;
public Runner2(Object stick) { this.stick = stick; }
public void run() {
// wait for Runner1
synchronized (stick) {
try { stick.wait();
} catch (InterruptedException e) { }
}
// at this point Runner1 is guaranteed
// to have finished his work
}
}



//*************** Conclusion: ***************//
Using a single object, two threads may schedule in what order they will run in accuracy.In the question you have posted, there two threads: Job and main. They schedule themselves based on the [B]thread[B] instance.It's just a choice to use this instance instead of any other object.Review:When thread A calls token.notify() it says: You may take the token.When thread B calls token.wait() it is waiting to take the token.Always synchronize on the token.

No comments: