java基礎——實現執行緒序列執行
阿新 • • 發佈:2019-01-01
為了控制執行緒執行的順序,如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; } }