亿元级IT行业生态链
一站式解决方案提供商

24小时免费咨询电话
010-52725243

阿甲集团

ABOUT AJIA

Java面试题中守护线程与用户线程的考查点

来源:阿甲问答 发布日期:2018-02-23

我们在面试Java岗位时,大多数的面试官都会问到这个问题守护线程与用户线程的关系这个问题。因此小编根据北京阿甲科技有限公司面试问题中遇到的关于守护线程与用户线程的问题以及在网上查阅完资料后为大家提供了一些关于守护线程与用户线程参考资料,希望对面试Java岗位的程序员们有所帮助。


一、守护线程与用户线程:


首先我们先来区分一下什么是守护线程什么是用户线程。


守护线程:


根据百度百科中关于守护线程的解释:守护线程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护线程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护线程从执行它的父进程(特别是shell)中继承下来的。最后,守护线程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。


用户线程:


根据百度百科中关于用户线程的解释: 指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。通俗的讲:


用户线程:我们平常创建的普通线程,守护线程:用来服务于用户线程;不需要上层逻辑介入。


通过一个例子来区分一下它们与JVM的关系。

class DaemonRunner implements Runnable {

@Override

public void run() {

while (true) {

for (int i = 1; i <= 100; i++) {

System.out.println("daemon thread:"+i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

Thread daemonThread = new Thread(new DaemonRunner());

daemonThread.setDaemon(true);

daemonThread.start();

System.out.println("isDaemon? = " + daemonThread.isDaemon());

Scanner scanner = new Scanner(System.in);

scanner.next();

Runtime.getRuntime().addShutdownHook(new Thread() {

@Override

public void run() {

System.out.println("JVM Exit!");

}

});


我们分析结果,可以得出结论:当线程只剩下守护线程的时候,JVM就会退出;补充一点如果还有其他的任意一个用户线程还在,JVM就不会退出。


二、使用它需要注意些什么?


1. thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。

2. 在Daemon线程中产生的新线程也是Daemon的。

3. 守护线程不能用于去访问固有资源,比如读写操作或者计算逻辑。因为它会在任何时候甚至在一个操作的中间发生中断。

4. Java自带的多线程框架,比如ExecutorService,会将守护线程转换为用户线程,所以如果要使用后台线程就不能用Java的线程池。


三、意义及应用场景:


当主线程结束时,结束其余的子线程(守护线程)自动关闭,就免去了还要继续关闭子线程的麻烦。如:Java垃圾回收线程就是一个典型的守护线程;内存资源或者线程的管理,但是非守护线程也可以。


免责声明:本文来源于微信公众号上面的文章,感谢原作者的分享。本文旨在分享提供阅读版权归原作者所有,如有侵权请联系我们进行删除。

欢迎访问阿甲科技集团官方网站!