理解執行緒的join方法
阿新 • • 發佈:2019-01-02
在多執行緒環境下很難保證結果的一致性,多執行緒帶來的好處就是並行處理提升效率,弊端就是出現了問題很難定位,可以看個例子就明白了,請將下面的程式碼拷到本地去執行,就會發現每次執行的結果不一樣。
程式碼1
public class JoinDemo { public static void main(String[] args) { Thread thread1 = new Thread(()->{ System.out.println("1"); }); Thread thread2 = new Thread(()->{ System.out.println("2"); }); Thread thread3 = new Thread(()->{ System.out.println("3"); }); thread1.start(); thread2.start(); thread3.start(); } }
怎麼樣才能每次結果都是123,那麼就需要使用join。看下面的程式碼
程式碼2
public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(()->{ System.out.println("1"); }); Thread thread2 = new Thread(()->{ System.out.println("2"); }); Thread thread3 = new Thread(()->{ System.out.println("3"); }); thread1.start(); thread1.join(); thread2.start(); thread2.join(); thread3.start(); } }
為什麼現在無論程式執行多少次,結果都是123,那就需要去看看join的原始碼到底做了什麼如此神奇。
程式碼3
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } // 傳入的就是0 if (millis == 0) { while (isAlive()) { // 等待0秒,起到阻塞的作用 wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } }
好,那我們是否能自己寫程式碼實現join方法類似的功能呢?當然可以,對程式碼2進行稍微的修改就可以了。
thread1.start();
Thread.sleep(3);
thread2.start();
Thread.sleep(3);
thread3.start();
多執行緒還有很多技術能控制執行緒的執行和阻塞,通過阻塞實現一些意向不到的效果,後續再分享。