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

  能够从上面的运行结果中看出用户线程和守护线程的区别了!

相关文章
相关标签/搜索