1. 程式人生 > >java基礎——實現執行緒序列執行

java基礎——實現執行緒序列執行

為了控制執行緒執行的順序,如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;
    }
}