今天看Java一个关于多线程返回值方式的示例,发现一个自己不太能理解的问题,就是在主线程中启动了几个工作线程,主线程中也没有join,工作线程居然也是正常输出了回调的结果。这个跟linux C++下的线程知识可是不一样的,在C++下,如果main函数退出了,那么所有的子线程也就退出了,我一开始怀疑是不是书上写的不够仔细,没有测试,所以自己写了几个类简单的测试了一下。代码如下:

  ThreadCallback.java代码:

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代码:

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也会等所有用户线程都执行完毕才退出。

  而守护线程会在所有用户线程(包括主线程)退出之后,一起退出,这时候JVM也就退出了。

  我们把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"然后就退出了。

  如果我们将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

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

Java用户线程和守护线程的更多相关文章

  1. 【java多线程】用户线程和守护线程的区别

    java中线程分为两种类型:用户线程和守护线程.通过Thread.setDaemon(false)设置为用户线程:通过Thread.setDaemon(true)设置为守护线程.如果不设置次属性,默认 ...

  2. java高并发系列 - 第9天:用户线程和守护线程

    守护线程是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回收线程.JIT线程都是守护线程.与之对应的是用户线程,用户线程可以理解为是系统的工作线程,它会完成这个程序需要完成的业务操作.如果 ...

  3. java 用户线程和守护线程

    在Java中通常有两种线程:用户线程和守护线程(也被称为服务线程)通过Thread.setDaemon(false)设置为用户线程通过Thread.setDaemon(true)设置为守护线程线程属性 ...

  4. java并发:初探用户线程和守护线程

    用户线程和守护线程 用户线程 用户线程执行完,jvm退出.守护线程还是可以跑的 /** * A <i>thread</i> is a thread of execution i ...

  5. 额!Java中用户线程和守护线程区别这么大?

    在 Java 语言中线程分为两类:用户线程和守护线程,而二者之间的区别却鲜有人知,所以本文磊哥带你来看二者之间的区别,以及守护线程需要注意的一些事项. 1.默认用户线程 Java 语言中无论是线程还是 ...

  6. Java:多线程<四> Lock、停止线程、守护线程、join、优先级&yield

    Java1.5以后,Condition将Object监视器方法(wait, notify, notifyAll)分解成截然不同的对象,以便通过这些对象与任意Lock实现组合使用为每个对像提供多个等待s ...

  7. Java中的守护线程 & 非守护线程(简介)

    Java中的守护线程 & 非守护线程 守护线程 (Daemon Thread) 非守护线程,又称用户线程(User Thread) 用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守 ...

  8. Java多线程编程之守护线程

    Java的线程分为两种,一个是用户线程,一个是守护线程.守护线程守护的对象就是用户线程,当用户线程结束后,守护它的守护线程也就会结束.二者的本质基本是一样的,唯一区别在于何时结束. 用户线程:直到自己 ...

  9. JAVA笔记13__创建线程/线程休眠/等待线程终止/线程中断/守护线程

    /** * 线程:是进程的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程最少有一个进程(单线程程序) * 多线程两种实现方法:1.继承Thread类 2.实现Runnable ...

随机推荐

  1. 超酷震撼 HTML5/CSS3动画应用及源码

    HTML5可以制作非常华丽的动画效果,这点通过之前的分享学习我们已经有深刻的了解了,今天我们主要来分享一些HTML5结合CSS3形成的超炫震撼的动画应用以及它们的源代码,真的非常不错. 1.纯CSS3 ...

  2. iOS开发_内存泄漏、内存溢出和野指针之间的区别

    今天,在工作群中,被问到了内存泄漏和野指针指向的区别,自己答的不是很好,特意回来查了资料,在博文中总结一下经验,欢迎指正. 内存泄漏:是指在堆区,alloc 或new 创建了一个对象,但是并没有放到自 ...

  3. 实验7 BindService模拟通信

    实验报告 课程名称 基于Android平台移动互联网开发 实验日期 2016.4.16 实验项目名称 BindService模拟通信 实验地点 S30010 实验类型 □验证型    √设计型    ...

  4. bzoj 3611: [Heoi2014]大工程

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  5. js写的闹钟,支持多个闹钟

    因为玩一个游戏,该游戏可以支持多个号,每个号有好多等时间的任务. 来回切换看,太耽误时间.手机的闹钟操作太麻烦. 所以写了一个使用配置文件的闹钟,简单方便. var ForReading = 1, F ...

  6. uva 489 Hangman Judge

    大意:电脑想个单词,玩家来猜.玩家输入一个个字母,若答案里有这个字母,则显示该单词中所有该字母.最终目标是显示答案所有字母.猜错7次,死: 注意特殊条件:1.玩家不断重复错误的字母,只算一次猜错.2. ...

  7. 前端:IE兼容性的相关方法

    有一段时间做前端的时候,IE下的就兼容性是比较令人头痛的问题,我在这一过程中也是看了很多的资料,然后把一些自己觉得比较普遍的问题进行一下相关的总结. 1.在IE6下,格式为png的图片在IE6上的透明 ...

  8. flex页面刷新实现

    页面刷新:navigateToURL(new URLRequest("javascript:location.reload();"),"_self"); 关闭浏 ...

  9. AngularJS身份验证:Cookies VS Tokens

    基于cookie的身份验证:Cookie-Based Authentication 基于token的身份验证:Token-Based Authentication 跨域:cross-domain 说明 ...

  10. tar命令的使用

    tar格式,会打包成一个文件,可以对多个目录,或者多个文件进行打包 tar命令只是打包,不会压缩,打包前后大小是一样的 tar命令 -c    //打包 -x    //解压 -f    //指定文件 ...