java的守护进程与非守护进程

java的守护进程与非守护进程   


    最近重新研究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也就没啥线程好服务的了,所以虚拟机也就退出了。只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。守护线程最典型的应用就是 GC (垃圾回收器)。

       守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:

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字符串的

 

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

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

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

 

参考博文:https://blog.csdn.net/sujianxin2012/article/details/39324755


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双剑合璧————Spring Boot + Mybatis Plus

引言 最近在学习Mybatis Plus的使用,希望通过spring boot快速将mybatis plus整合进来。 对于springboot项目,mybatis plus团队也有自己的启动器 :mybatis-plus-boot-starter。这个依赖内部已经整合了mybatis-spring,也包括非快速…

Java中常用的类,包,接口

Java中常用的类,包,接口包名说明java.lang该包提供了Java编程的基础类,例如 Object、Math、String、StringBuffer、System、Thread等,不使用该包就很难编写Java代码了。java.util该包提供了包含集合框架、遗留的集合类、事件模型、…

Collection框架介绍

Collection:List列表,Set集, Map:Hashtable,HashMap,TreeMapCollection 是单列集合 List 元素是有序的、可重复 有序的 collection,可以对列表中每个元素的插入位置进行精确地控制。 可以根据…

Git初学札记(一)————Git简介与安装

前言 Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。(在这里再一次致敬Linus大神)特点 分布式相比于集中式的最…

Hashtable、HashMap、TreeMap总结

Hashtable、HashMap、TreeMap总结三者均实现了Map接口,存储的内容是基于key-value的键值对映射,一个映射不能有重复的键,一个键最多只能映射一个值。 (元顺初线)(1) 元素特性HashTable中的key、…

Git初学札记(二)————EGit导入远程Git仓库项目(Clone操作)

引言 我们在实际开发项目的时候,难免要使用像Eclipse或者IDEA这样的继承开发工具,除了部分“牙牙学语”的程序员需要手动输入javac去编译程序以外,在实际开发中手动编译并运行项目的“猿族”应该是已经绝种了。 我个人认为,使用gi…

int和Integer的比较

int和Integer的比较1 int和IntegerJDK1.5引入了自动装箱与自动拆箱功能,Java可根据上下文,实现int/Integer,double/Double,boolean/Boolean等基本类型与相应对象之间的自动转换,为开发过程带来极大便利。最常用的是通过new方法构建Integer对象…

Git初学札记(三)————创建Git版本库

引言 版本库即所谓的Git仓库,英文名称是Repository,可以简单理解为一个目录(.git folder),这个目录可以记录并保存直接父级及其子目录下的全部文本文件的修改操作,谓之“版本控制”! 手动建库 不…

Git初学札记(四)————Git Push的常规操作与Pull冲突解决

目录 引言 Git命令行的远程Push EGit Push操作中的冲突问题 同步 工作区与本地库同步 工作区与远程库同步 图标 重点 引言 在团队开发当中,Git Push是多人协作环节中的最重要的一环可能没有之一。同SVN一样,push操作可以看做是对远端程序的提交…

一篇博客读懂设计模式之---动态代理与反射

一篇博客读懂设计模式之---动态代理与反射 先来讲一下反射: 1 关于反射反射最大的作用之一就在于我们可以不用在编译时就知道某个对象的类型,而在运行时通过提供完整的”包名类名.class”得到。注意:不是在编译时,而是在运行时。…

Git初学札记(五)————Branch分支管理

引言 正如之前的博客中提到的,Git区别于Svn的一个最明显的功能就是分支管理功能。 那么什么是分支?分支又能为我们的开发带来什么翻天覆地的变化呢?(为了使博客的内容更具权威性和专业性,以下部分内容摘自官方文档《Gi…

多线程中 start()和run()方法的区别

多线程中 start()和run()方法的区别:Java线程一直是一个比较容易困扰的地方,首先,我们来认识下怎样生存线程。认识 Thread 和Runnablejava中实现多线程有两种途径:继承Thread类或者实现Runnabl…

Git初学札记(六)————在远程新建本地Branch与在本地新建远程Branch

引言 本篇博客介绍将现有的本地分支以新的分支形式推送到远程库中,和以新的分支的形式从远程库中拉取一个分支。这两个功能都是比较简单的操作,但是在实际开发中,可能会在开发初期有所触及。比如我们希望将远程的dev分支拉取到本地来进行开发…

Git初学札记(七)————合并分支(merge)

目录 引言 开始Merge 1、History视图 2、Team菜单 3、Git Repositories视图 巧用Git Staging视图 放弃Merging 可能的Merge结果 引言 Git鼓励开发者使用分支来进行程序的开发。但是最终只会有一个版本发行出去,因此,我们需要将开发好的分支merg…

公钥,私钥和数字签名这样理解轻松入门!

公钥,私钥和数字签名这样理解轻松入门!参考博文:https://blog.csdn.net/21aspnet/article/details/7249401 (公钥和私钥是成对出现的,可以把他们看成锁头和钥匙的关系,公钥为锁头,私钥是钥匙&am…

Spring Boot + JSP

目录 引言 Maven依赖 JSP页面 application.properties配置 controller 结果展示 引言 在尝试使用shiro的时候需要页面登录的加持,但是长期的前后端分离工作,导致页面的知识几乎忘光。突然想通过jsp这种简单的形式来学习其他的技术,作为…

https和http的区别

https和http的区别一、基本概念(http服务器-->本地浏览器,正确快速传输;https安全套接字层,http的安全版本, httpssl层,建立一个信息安全的通道,保证数据传输的安全,确认网站的…

Markdown简明使用

#Markdown使用技巧 ##代码背景 可以使用反引号,来将特殊文字括起来,这样Markdown会自动为引号中的内容加入背景。 形如:内容 例如:Java project > team > share project ##图片上传 图片无法像正常的文本编辑器那样直接粘贴…

Spring Boot + Mybatis 快速整合

引言 最近在工作结束后抽时间学习了一下mybatis的知识,因为之前有学习过,但是经久不用,也未曾踏实地整理,因此有所淡忘。 super meeting会议管理系统是我厂最近开发的一套会议预约平台。持久层框架经讨论,选为灵活优…

SQL关联查询————LEFT JOIN关键字的使用

引言 关联查询一直是非常重要的SQL使用技巧。 在一次查询操作中&#xff0c;使用mybatis进行条件查询&#xff0c;在没有使用 LEFT JOIN 关键字的情况下是这样写的&#xff1a; <!-- 查找成员 --><select id"selectUsers" resultMap"selectUsers_Res…