转自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;
- }
- }