转自http://my.oschina.net/mingyuanwang/blog/493281?p=1
为了控制线程执行的顺序,如ThreadA->ThreadB->ThreadC->ThreadA循环执行三个线程,我们需要确定唤醒、等待的顺序。这时我们可以同时使用 Obj.wait()、Obj.notify()与synchronized(Obj)来实现这个目标。
通常情况下,wait是线程在获取对象锁后,主动释放对象锁,同时本线程休眠,直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。而notify()则是对等待对象锁的线程的唤醒操作。但值得注意的是notify()调用后,并不是马上就释放对象锁,而是在相应的synchronized(){}语句块执行结束。释放对象锁后,JVM会在执行wait()等待对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。
public class ThreadSerialize {
public static void main(String[] args){
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB();
ThreadC threadC = new ThreadC();
threadA.setThreadC(threadC);
threadB.setThreadA(threadA);
threadC.setThreadB(threadB);
threadA.start();
threadB.start();
threadC.start();
while (true){
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ThreadA extends Thread{
private ThreadC threadC;
@Override
public void run() {
while (true){
synchronized (threadC){
synchronized (this){
System.out.println("I am ThreadA。。。");
this.notify();
}
try {
threadC.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void setThreadC(ThreadC threadC) {
this.threadC = threadC;
}
}
class ThreadB extends Thread{
private ThreadA threadA;
@Override
public void run() {
while (true){
synchronized (threadA){
synchronized (this){
System.out.println("I am ThreadB。。。");
this.notify();
}
try {
threadA.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void setThreadA(ThreadA threadA) {
this.threadA = threadA;
}
}
class ThreadC extends Thread{
private ThreadB threadB;
@Override
public void run() {
while (true){
synchronized (threadB){
synchronized (this){
System.out.println("I am ThreadC。。。");
this.notify();
}
try {
threadB.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void setThreadB(ThreadB threadB) {
this.threadB = threadB;
}
}