1. 程式人生 > >Daemon執行緒和Join執行緒

Daemon執行緒和Join執行緒

1、Daemon執行緒


  Daemon執行緒稱為守護執行緒(非常喜歡這個名字)。執行緒一旦被設定為守護執行緒,當非守護執行緒結束,守護執行緒即使沒有執行完,也必須隨之全部結束。例如我們曾經玩兒過的坦克大戰,一旦守護的老巢完蛋了,其它守護坦克沒死也要結束。

  Daemon執行緒的實質作用是為主執行緒其他執行緒的執行提供服務。User Thread執行緒和Daemon Thread守護執行緒本質上來說去沒啥區別的,唯一的區別之處就在虛擬機器的離開:如果User Thread全部撤離,那麼Daemon Thread也就沒啥執行緒好服務的了,所以虛擬機器也就退出了。

  設定守護執行緒方法:

public final void setDaemon(boolean on) ;但是有幾點需要注意:

    thread.setDaemon(true)必須在thread.start()之前設定,否則會丟擲IllegalThreadStateException異常。因為我們不能夠將正在執行的常規執行緒設為守護執行緒。

    在Daemon執行緒中產生的新執行緒也是Daemon的。

    不是所有的應用都可以分配給Daemon執行緒來進行服務,比如讀寫操作或者計算邏輯。我們必須防止在Daemon Thread還沒來的及進行操作時,虛擬機器可能已經退出了。


2、Daemon例項


  (1)待設定為Daemon執行緒的執行緒類


<span style="font-size:18px;">//實現Runnable介面
public class DaemonDemo implements Runnable {
	
	//重寫run方法
	@Override
	public void run() {
		for (int x = 0; x < 1000; x++) {
			System.out.println(Thread.currentThread().getName() + "---" + x);
		}
	}
}</span>

  (2)測試類


<span style="font-size:18px;">public class DaemonDemoTest {
	public static void main(String[] args) {
		DaemonDemo dd = new DaemonDemo();

		Thread t1 = new Thread(dd);
		Thread t2 = new Thread(dd);
		
		//將t1、t2設定為守護執行緒,注意要在start()方法呼叫之前設定
		t1.setDaemon(true);
		t2.setDaemon(true);

		t1.start();
		t2.start();

		for (int x = 0; x < 10; x++) {
			System.out.println(Thread.currentThread().getName() + "---" + x);
		}
	}
}</span>

  執行結果:main執行緒中的10次迴圈結束時,兩個沒有執行結束的守護執行緒都會隨之結束。


3、Join執行緒


  當執行緒被呼叫了Join()方法,那麼其它執行緒必須等待,直到本執行緒結束,其它執行緒才能執行。Join在英文中解釋為合併、加入,我更喜歡稱之為阻塞執行緒,程式必須首先執行完阻塞執行緒才能夠去執行其他執行緒。

  Join執行緒的作用:在很多情況下,主執行緒生成並起動了子執行緒,如果子執行緒裡要進行大量的耗時的運算,主執行緒往往將於子執行緒之前結束(正如我們上面的例子),但是如果主執行緒處理完其他的事務後,需要用到子執行緒的處理結果,也就是主執行緒需要等待子執行緒執行完成之後再結束,這個時候就要用到join()方法了。


4、Join執行緒例項


  (1)待設定執行緒類


<span style="font-size:18px;">public class JoinDemo implements Runnable {

	@Override
	public void run() {
		for (int x = 0; x < 100; x++) {
			System.out.println(Thread.currentThread().getName() + "---" + x);
		}
	}
}</span>

  (2)測試類


<span style="font-size:18px;">public class JoinDemoTest {
	public static void main(String[] args) {
		PriorityDemo pd = new PriorityDemo();

		Thread t1 = new Thread(pd);
		Thread t2 = new Thread(pd);
		Thread t3 = new Thread(pd);

		t1.setName("執行緒一");
		t2.setName("執行緒二");
		t3.setName("執行緒三");

		t2.start();
		// join()執行緒 加入執行緒
		try {
			t2.join(); //必須首先將t2執行完畢才能去執行其它執行緒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		t1.start();
		t3.start();
	}
}</span>

  執行結果:首先結束t2執行緒之後才會執行t1和t3執行緒。