標籤:test ace exce imp 執行 stack 阻塞 png exception
Thread線程join方法自我理解
thread.join():等待thread線程運行終止,指的是main-thread(main線程)必須等待thread線程運行結束,才能繼續thread.join();後面的代碼
thread.join(long time):線程thread等待time時間之後,main-thread可以執行,注意time時間後,線程thread沒有執行完,main-thread也可以運行
注意:上面2個方法必須線上程是alive的時候,才有這樣的效果,否則不會有。
join()方法源碼是有調用wait()方法的,wait方法是Object的方法,線程wait時,是釋放對象鎖的,所以調用join()方法是釋放對象鎖的線程阻塞同wait()方法。
class Runner1 implements Runnable{ @Override public void run() { try { System.out.println(Thread.currentThread().getName() + " begin..."); Thread.sleep(2000);//① } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " finish..."); }}class Runner2 implements Runnable{ @Override public void run() { try { System.out.println(Thread.currentThread().getName() + " begin..."); Thread.sleep(1000);//② } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " finish..."); }}public class Test_thread_join { /** * Thread.join()等待線程結束,再執行Thread.join後面的代碼 * Thread.join(n)等待線程結束或者n時間後,執行Thread.join後面的代碼 */ public static void main(String[] args) { Runner1 r1 = new Runner1(); Runner2 r2 = new Runner2(); Thread t1 = new Thread(r1, "Thread-A"); Thread t2 = new Thread(r2, "Thread-B"); t1.start();//t1是alive的 t2.start(); try { t1.join();//當執行這個代碼的時候,main線程阻塞,t2.這個線程可能運行著,也可能結束了 t2.join();//如果在t1.join()執行的時候,t2線程已經運行結束,那這行代碼是沒有效果的③ } catch (InterruptedException e) { e.printStackTrace(); } run(); } public static void run(){ for(int i = 0; i < 5; i++){ System.out.println("main i:" + i); } }}
大意:①Thread-A睡眠2秒,②Thread-B睡眠1秒
執行結果:
結論:t1.join();執行時,main方法阻塞等待t1線程執行完;t1線程執行完之後,程式執行t2.join(),此時t2線程已經死亡了運行結束了,這行代碼沒有效果沒有意義。如果t2沒有死亡,那麼main-thread,必須等待Thread-B死亡,才能執行後面的代碼。如果③這行代碼被注釋了,並且t1.join()執行完之後t2線程仍然是alive的,那麼main-thread和Thread-B線程將競爭CPU資源,他們的運行方式可能是互動。
Thread線程join方法自我理解