今天看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
能够从上面的运行结果中看出用户线程和守护线程的区别了!