Java用戶線程和守護線程

  今天看Java一個關於多線程返回值方式的示例,發現一個本身不太能理解的問題,就是在主線程中啓動了幾個工做線程,主線程中也沒有join,工做線程竟然也是正常輸出了回調的結果。這個跟linux C++下的線程知識但是不同的,在C++下,若是main函數退出了,那麼全部的子線程也就退出了,我一開始懷疑是否是書上寫的不夠仔細,沒有測試,因此本身寫了幾個類簡單的測試了一下。代碼以下:java

  ThreadCallback.java代碼:linux

package thread.callback;

public class ThreadCallback {
    public void callBack(String msg) {
        System.out.println(msg);
    }
}

  WorkThread.java代碼:多線程

package thread.callback;

public class WorkThread extends Thread{
    private ThreadCallback callback;
    private String threadName;
    public WorkThread(ThreadCallback _callback, String _threadName) {
        // TODO Auto-generated constructor stub
        this.callback = _callback;
        this.threadName = _threadName;
    }
        
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.callback.callBack(this.threadName);
    } 
}

  test.java代碼:ide

package thread.callback;

public class test {
    public static void main(String[] args) {
        for (int i=0; i<5; ++i) {
            ThreadCallback callback = new ThreadCallback();
            WorkThread workThread = new WorkThread(callback, "thread" + Integer.toString(i));
            workThread.start();
            
        }
        
        System.out.println("to be end");
    }
}

  代碼很是簡單啊,就是WorkThread中簡單回調Callback中的接口,而後再callback中打印一下,運行的結果以下:函數

to be end
thread0
thread2
thread3
thread1
thread4

  從輸出結果(thread輸出順序,每次不必定同樣)能夠看出來,主線程退出以後,其建立的幾個子線程仍是在正常運行的,直到輸出了指定的結果。那麼也就是跟以前linux C++下的主從線程關係不太同樣了。通過搜索,發現Java線程有一個是否爲守護線程的屬性,默認狀況下這個屬性是不設置的,爲false,表明這個線程是一個用戶線程,若是使用Thread的setDaemon接口設置一下,那麼線程屬性就會變成守護線程。測試

  用戶線程不會隨着主線程退出而結束,而是會繼續在JVM中運行的,直到自身結束,JVM也會等全部用戶線程都執行完畢才退出。this

  而守護線程會在全部用戶線程(包括主線程)退出以後,一塊兒退出,這時候JVM也就退出了。spa

  咱們把test.java改爲這樣:線程

package thread.callback;

public class test {
	public static void main(String[] args) {
		for (int i=0; i<5; ++i) {
			ThreadCallback callback = new ThreadCallback();
			WorkThread workThread = new WorkThread(callback, "thread" + Integer.toString(i));
			workThread.setDaemon(true);
			workThread.start();
			
		}
		
		System.out.println("to be end");
	}
}

  新增setDaemon,在thread運行以前設置,而後運行程序,程序只打印"to be end"而後就退出了。code

  若是咱們將5個子線程中的4個設置爲守護線程,一個爲用戶線程,會怎樣呢?

  test.java代碼

package thread.callback;

public class test {
	public static void main(String[] args) {
		for (int i=0; i<5; ++i) {
			ThreadCallback callback = new ThreadCallback();
			WorkThread workThread = new WorkThread(callback, "thread" + Integer.toString(i));
			if (i != 4)
				workThread.setDaemon(true);
			workThread.start();
			
		}
		
		System.out.println("to be end");
	}
}

  那麼也會可能輸出全部線程結果。爲啥說可能呢,這要看惟一的用戶線程thread4啥時候退出了,它一退出,那麼其餘守護進程無論有沒有執行完,都會被迫退出。在咱們上面的例子中比較難出現,由於thread4是最後一個啓動的,並且你們都作相同簡單的事情,若是把thread4改爲thread1,那麼就很是容易測試出來了。

  好比咱們把WorkThread.java的run改爲這樣:

public void run() {
        // TODO Auto-generated method stub
        try {
            if (threadName.equals("thread4"))
                Thread.sleep(1000);
            else
                Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.callback.callBack(this.threadName);
    } 

  那麼輸出結果就是:

to be end
thread4

  能夠從上面的運行結果中看出用戶線程和守護線程的區別了!

相關文章
相關標籤/搜索