1、join
public class JoinThreadTest extends Thread { public JoinThreadTest(String name){ super(name); } @Override public void run() { for(int i = 0; i < 100; i++){ System.out.println(getName() + " " + i); } } public static void main(String[] args) { for(int i = 0; i < 1000; i++){ if (i== 20) { JoinThreadTest joinThreadTest = new JoinThreadTest("JoinThread"); joinThreadTest.start(); try { joinThreadTest.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " " + i); } } }
當調用join方法後,主線程將進入阻塞狀態,直到被join()方法加入的join線程執行完成為止。通常用來將大問題化為小問題,每個小問題分配一個線程,當這些小問題線程執行完成後,再調用主線程做進一步的處理。
2、後台線程Daemon
主線程默認是前台線程,由前台線程創建的線程默認是前台線程,由後台線程創建的線程默認為後台線程。當所有的前台線程都死亡後,後台線程會自動死亡。設置線程為後台線程,調用setDaemon(true)必須在start()之前調用,判斷一個線程是否為後台線程可用isDaemon()判斷。
public class DaemonThreadTest extends Thread{ public DaemonThreadTest(String name){ super(name); } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(getName() + " " + i); } } public static void main(String[] args) { DaemonThreadTest daemonThreadTest = new DaemonThreadTest("DaemonThread"); daemonThreadTest.setDaemon(true); daemonThreadTest.start(); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } } }
運行如上代碼後可知,DaemonThread不會輸出到999,而是當主線成執行完後,過了一段時間後,DaemonThread也就結束了。
3、sleep 和 yield
sleep調用後使線程進入阻塞狀態,在該線程的睡眠時間內,即使cpu空閒,線程也不會獲得執行機會。睡眠結束後,線程進入就緒狀態,等待調度進入運行狀態。對所有優先級的線程有效。
yield 只是簡單讓當前線程暫停一下,使線程調度器重新調度,只對優先級大於等於當前線程的線程有效。當前線程也有可能在暫停一下後,立即調度再次進入運行態。
另外調用sleep會拋出InterruptException,而yield不會。
public class YieldTest extends Thread { public YieldTest(String name) { super(name); } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(getName() + " " + i); if (i== 20) { Thread.yield(); } } } public static void main(String[] args) { YieldTest yieldTest1 = new YieldTest("High"); yieldTest1.setPriority(MAX_PRIORITY); yieldTest1.start(); YieldTest yieldTest2 = new YieldTest("Low"); yieldTest2.setPriority(MIN_PRIORITY); yieldTest2.start(); } }
由於如上代碼設置了不同優先級,執行如上代碼,當執行到i==20時,High線程雖然讓出資源,但是優先級高,重新調度後,還是High線程繼續執行,注釋掉設置優先級的兩行代碼後執行,可發現在i==20後,線程調度,High線程會出讓資源給Low運行。
4、改變線程的優先級
線程優先級設置如上例,子線程的優先級默認與父線程的優先級一致。