2 u010758482 u010758482 于 2016.09.13 00:31 提问

java 后台线程中创建一个线程问题求解

今晚在看Think In Java的时候,看到后台线程这一小节,突然有个想法,如果在一个守护线程里面创建一个非守护线程(不显示的设置setDaemon(true)),那么创建的非守护线程是否也变成了守护线程。
代码如下
package com.hq.day0601;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**

  • 简单的后台线程(守护线程)练习,该练习主要演示的是后台线程在最后一个非后台线程结束后,也会被关闭
  • @author Administrator * */ public class SimpleDaemons implements Runnable {

@Override
public void run() {
try {
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new TestThread());
TimeUnit.MILLISECONDS.sleep(100);
System.out.println("SimpleDaemons is Daemons:"+Thread.currentThread().isDaemon());
System.out.println(Thread.currentThread() +" "+this );

} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("sleep() Interrupted");
}
}

public static void main(String[] args) throws Exception {
for(int i = 0 ; i < 3;i++){
Thread daemons = new Thread(new SimpleDaemons());
daemons.setDaemon(true);
daemons.start();
}
System.out.println("daemons start!");
TimeUnit.SECONDS.sleep(1);
}

}

/**

  • 校验守护线程中创建的线程是否是守护线程
  • @author Administrator * */ class TestThread implements Runnable { @Override public void run() { System.out.println("TestThread is Daemon:"+Thread.currentThread().isDaemon()); } }

打印结果:

从打印结果观察到,在后台线程中创建的线程不是后台线程。
然后,我对代码进行了改造,加上while循环
代码如下:
package com.hq.day0601;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**

  • 简单的后台线程(守护线程)练习,该练习主要演示的是后台线程在最后一个非后台线程结束后,也会被关闭
  • @author Administrator
    *
    */
    public class SimpleDaemons implements Runnable {

    @Override
    public void run() {

    try {
    ExecutorService exec = Executors.newCachedThreadPool();
    exec.execute(new TestThread());
    while(true){//添加while循环
    TimeUnit.MILLISECONDS.sleep(100);
    System.out.println("SimpleDaemons is Daemons:"+Thread.currentThread().isDaemon());
    System.out.println(Thread.currentThread() +" "+this );
    }
    } catch (InterruptedException e) {

    e.printStackTrace();
    System.out.println("sleep() Interrupted");
    }

    }

    public static void main(String[] args) throws Exception {
    for(int i = 0 ; i < 3;i++){
    Thread daemons = new Thread(new SimpleDaemons());
    daemons.setDaemon(true);
    daemons.start();
    }
    System.out.println("daemons start!");
    TimeUnit.SECONDS.sleep(1);
    }

}

/**

  • 校验守护线程中创建的线程是否是守护线程
  • @author Administrator * */ class TestThread implements Runnable { @Override public void run() { System.out.println("TestThread is Daemon:"+Thread.currentThread().isDaemon()); } } 我以为程序会在一秒后终止。但是却出了一个奇怪的现象,控制台一直在打印while循环里要打印的内容, 这让我感到非常费解,不知道有没有哪个大神讲解下这是什么原因。

1个回答

qli
qli   2016.09.13 04:06

是你的Java VM中还有一个非daemon thread 还在运行

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
Java中后台线程详细解答
以前从来没有听说过,java中有后台线程这种东西。一般来说,JVM(JAVA虚拟机)中一般会包括俩种线程,分别是用户线程和后台线程。所谓后台线程(daemon)线程指的是:在程序运行的时候在后台提供的一种通用的服务的线程,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束的时候,也就是用户线程都结束的时候,程序也就终止了。同时,会杀死进程中的所有的后台线程。反过来说,只要有任何
java中的后台线程
java线程大家都不陌生,可以用继承Thread类或者实现Runable接口来定义一个自己的线程。另外,java线程还可以分为前台线程(也称用户线程或普通线程)和后台线程(Daemon thread),本篇就是要说明这两者的区别和用法。
将某一线程设置为后台线程
1、将线程设置为后台线程:与程序同生共死。比如垃圾回收器,长期运行,直到程序结束退出。 2、当线程不是后台线程时,主(服务线程)执行结束后,子线程没执行完的还继续执行直至运行结束。 3、当线程为后台线程时,主(服务线程)执行结束后,子线程没有执行完的不在执行。
java前台线程(普通线程) 和 后台线程
【1】普通线程: 就是指 用户 创建的一般线程,具有个体性,不具有提供公共服务的性质,因此, 通常需要我们在 线程的 循环语句中 手动编写 循环结束语句,也即 线程运行终止的条件语句; 【2】后台线程: 它有一个特性,即为用户线程 提供 公共服务,如 tomcat中的 监听器线程,它就是一个 后台线程,该线程用于监听 web容器 Session, Request 被销毁 或 创建的事件;
java前台线程和后台线程
一.  java中的后台线程:       java线程大家都不陌生,可以用继承Thread类或者实现Runable接口来定义一个自己的线程。另外,java线程还可以分为前台线程(也称用户线程或普通线程)和后台线程(Daemon thread),本篇就是要说明这两者的区别和用法。      1.  后台线程会随着主线程(main线程)的结束而结束,但是前台进程则不会(如果main线程先于前台进
java多线程中校验一个后台线程中创建一个新线程,新线程是否是后台线程
今晚在看Think In Java的时候,看到后台线程这一小节,突然有个想法,如果在一个守护线程里面创建一个非守护线程(不显示的设置setDaemon(true)),那么创建的非守护线程是否也变成了守护线程。 代码如下 package com.hq.day0601; import java.util.concurrent.ExecutorService; import java.u
前台线程和后台线程
<br />Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。 <br /><br /><br />一个线程是前台线程还是后台线程可由它的IsBackground属性来决定。这个属性是可读又可写的。它的默认值为false,即意味着一个线程默认为前台线程。我们可以将
在VB中创建多线程
在VB中创建线程用到以下几个API函数:创建线程API此API经过改造,lpThreadAttributes改为Any型,lpStartAddress改为传值引用:因为函数入口地址是由形参变量传递,如果用传址那将传递形参变量的地址而不是函数的入口地址 参数dwStackSize为应用程序堆栈大小,lpStartAddress为函数入口地址Private Declare
C#后台线程和UI的交互
在C#中,从Main()方法开始一个默认的线程,一般称之为主线程,如果在这个进行一些非常耗CPU的计算,那么UI界面就会被挂起而处于假死状态,也就是说无法和用户进行交互了,特别是要用类似进度条来实时显示一些提示信息的时候,这种情况就显得很糟糕。如果多开一些线程来完成一些耗时的计算,那么工作线程也是无法如此更新UI界面中的元素的,比如直接显示一个提示信息:label1.Text=outstring,
建立一个ASP.NET的Server端后台线程
有时候我们需要ASP.NET的server端一直运行一个后台线程,进行一些如刷新网页,检查某些网址之类的工作,当然我们还需要可以控制这个线程开始和结束,且保证不会过多的建立线程。这些可以通过一个静态的的System.Threading类成员来实现(在示例线程中,我们反复把当前时间写入一个文本文件中),代码如下:using System;using System.Data;using System.