浅谈java的守护线程与非守护线程

作者:super-d2 时间:2023-11-25 06:50:23 

最近重新研究Java基础知识,发现以前太多知识知识略略带过了,比较说Java的线程机制,在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) ,(PS:以前忽略了)。

估计学过Unix开发但是没有细致学习Java的同学们会疑惑了,操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是Java语言机制是构建在JVM的基础之上的,意思是Java平台把操作系统的底层给屏蔽起来,所以它可以在它自己的虚拟的平台里面构造出对自己有利的机制,而语言或者说平台的设计者多多少少是收到Unix思想的影响,而守护线程机制又是对JVM这样的平台凑合,于是守护线程应运而生。

Daemon的作用是为其他线程的运行提供服务,比如说GC线程。其实User Thread线程和Daemon Thread守护线程本质上来说去没啥区别的,唯一的区别之处就在虚拟机的离开:如果User Thread全部撤离,那么Daemon Thread也就没啥线程好服务的了,所以虚拟机也就退出了。

守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:public final void setDaemon(boolean on) ;但是有几点需要注意:

1)、thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。  (备注:这点与守护进程有着明显的区别,守护进程是创建后,让进程摆脱原会话的控制+让进程摆脱原进程组的控制+让进程摆脱原控制终端的控制;所以说寄托于虚拟机的语言机制跟系统级语言有着本质上面的区别)

2)、 在Daemon线程中产生的新线程也是Daemon的。  (这一点又是有着本质的区别了:守护进程fork()出来的子进程不再是守护进程,尽管它把父进程的进程相关信息复制过去了,但是子进程的进程的父进程不是init进程,所谓的守护进程本质上说就是“父进程挂掉,init收养,然后文件0,1,2都是/dev/null,当前目录到/”)

3)、不是所有的应用都可以分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。因为在Daemon Thread还没来的及进行操作时,虚拟机可能已经退出了。

例子:


//完成文件输出的守护线程任务

import java.io.*;

class TestRunnable implements Runnable{

public void run(){

try{

Thread.sleep(1000);//守护线程阻塞1秒后运行

File f=new File("daemon.txt");

FileOutputStream os=new FileOutputStream(f,true);

os.write("daemon".getBytes());

}

catch(IOException e1){

e1.printStackTrace();

}

catch(InterruptedException e2){

e2.printStackTrace();

}

}

}

public class TestDemo2{

public static void main(String[] args) throws InterruptedException

{

Runnable tr=new TestRunnable();

Thread thread=new Thread(tr);

thread.setDaemon(true); //设置守护线程

thread.start(); //开始执行分进程

}

}

运行结果:文件daemon.txt中没有"daemon"字符串。

但是如果把thread.setDaemon(true); //设置守护线程注释掉,文件daemon.txt是可以被写入daemon字符串的

浅谈java的守护线程与非守护线程 

JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台线程候一定要注意这个问题。

但是daemon Thread实际应用在那里呢?举个例子,web服务器中的Servlet,容器启动时后台初始化一个服务线程,即调度线程,负责处理http请求,然后每个请求过来调度线程从线程池中取出一个工作者线程来处理该请求,从而实现并发控制的目的。

网上摘的一个图,方便大家理解:

浅谈java的守护线程与非守护线程 

来源:http://www.cnblogs.com/super-d2/p/3348183.html

标签:java,守护线程,非守护线程
0
投稿

猜你喜欢

  • Android中实现iOS中的毛玻璃效果

    2023-01-27 01:44:14
  • 基于android studio的layout的xml文件的创建方式

    2022-10-31 10:52:06
  • springboot+jwt实现token登陆权限认证的实现

    2021-12-22 12:02:46
  • android使用OPENGL ES绘制圆柱体

    2021-12-26 15:22:00
  • 优化SimpleAdapter适配器加载效率的方法

    2022-03-10 20:33:32
  • 通过openOffice将office文件转成pdf

    2021-12-29 21:35:32
  • 分享几个Java工作中实用的代码优化技巧

    2023-11-28 12:04:50
  • Mybatis Limit实现分页功能

    2022-03-14 13:57:57
  • Java利用自定义注解、反射实现简单BaseDao实例

    2022-09-06 05:29:30
  • java项目中的多线程实践记录

    2023-10-16 16:12:03
  • C#调用Java类的实现方法

    2022-10-30 11:00:10
  • C#应用BindingSource实现数据同步的方法

    2021-07-09 16:15:48
  • C# 8.0可空引用类型的使用注意记录

    2022-10-03 23:29:40
  • Java 实现常见的非对称加密算法

    2023-11-27 18:51:03
  • Android Init进程对信号的处理流程详细介绍

    2022-10-25 18:03:31
  • Android实现给TableLayou绘制边框的方法

    2021-08-04 02:08:41
  • Java进程间通信之消息队列

    2023-05-24 01:44:27
  • 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic

    2022-03-26 18:43:02
  • Java深入讲解static操作符

    2023-11-27 00:59:16
  • Android性能优化大图治理示例详解

    2023-12-13 00:18:01
  • asp之家 软件编程 m.aspxhome.com