Java多线程之守护线程

一、前言

  • Java线程有两类:

    • 用户线程:运行在前台,执行具体的任务,程序的主线程,连接网络的子线程等都是用户线程

    • 守护线程:运行在后台,为其他前台线程服务

      • 特点:一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作

      • 应用:数据库连接池中的监测线程JVM启动后的监测线程

      • 最常见的守护线程:垃圾回收线程

      • 如何设置守护线程:可以通过Thread类的setDaemon(true)方法来设置当前的线程为守护线程

  • 注意事项:

    • setDaemon(true)必须在start方法之前调用,否则会抛出IllegalThreadStateException异常

    • 在守护线程中产生的新线程也是守护线程

    • 不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑

二、代码分析:

 package me.demo.daemon;

 import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Scanner; class DaemonThread implements Runnable { @Override
public void run() {
System.out.println("进入守护线程:" + Thread.currentThread().getName());
try {
WriteToFile();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("退出守护线程:" + Thread.currentThread().getName());
} private void WriteToFile() throws Exception {
File file = new File("E:" + File.separator + "daemon.txt");
// true代表追加操作
OutputStream os = new FileOutputStream(file, true);
int count = 0;
while (count < 999) {
os.write(("\r\nword" + count).getBytes());
System.out.println("守护线程" + Thread.currentThread().getName() + "向文件中写入了Word" + count++);
Thread.sleep(1000);
}
os.close();
} } public class DaemonThreadDemo { public static void main(String[] args) {
System.out.println("进入主线程:" + Thread.currentThread().getName());
DaemonThread daemonThread = new DaemonThread();
Thread thread = new Thread(daemonThread);
thread.setDaemon(true); // 设为守护线程
thread.start(); /**
* 主线程阻塞等待键盘输入 由于此时主线程是唯一的用户线程 所以当主线程退出,则守护线程也会退出
* 即while循环提前退出,导致守护线程写入数据的不完整性
*/
Scanner input = new Scanner(System.in);
input.next();
input.close();
System.out.println("退出主线程:" + Thread.currentThread().getName());
}
}

  运行这个程序,如果我们不做任何操作,他将会向E盘下的daemon.txt文件写入数据,直到while循环结束,并先后打印出退出守护线程和退出主线程字段信息,期间我们如果向控制台输入任意字符串并回车,由于主线程阻塞等待键盘输入,并且此时主线程是唯一的用户线程 所以当主线程退出,则守护线程也会退出,即while循环提前退出,导致守护线程写入数据的不完整性,这正应证了我上面提到的守护线程的特点:一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博文感兴趣,可以关注我的后续博客,我是【AlbertRui】。

转载请注明出处及链接地址,欢迎转载!

Java多线程之守护线程的更多相关文章

  1. java多线程之守护线程与非守护线程

    在java线程中有两种线程,一种是用户线程,其余一种是守护线程. 守护线程具有特殊的含义,比如gc线程.当最后一个非守护线程执行完后,守护线程随着jvm一同结束工作. java中的守护线程需要将Dae ...

  2. java多线程之守护线程以及Join方法

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.守护线程概述及示例 守护线程就是为其它线程提供"守护"作用,说白了就是为其它线程服务的,比如GC线程. java程序中线程分 ...

  3. java多线程之守护线程(Daemon)

    https://blog.csdn.net/u010739551/article/details/51065923/

  4. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  5. Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗

    在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...

  6. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  7. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  8. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  9. Java多线程系列--“JUC线程池”05之 线程池原理(四)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

随机推荐

  1. 十一、SQL Server CONVERT() 函数

    定义和用法 CONVERT() 函数是把日期转换为新数据类型的通用函数. CONVERT() 函数可以用不同的格式显示日期/时间数据. 语法 CONVERT(data_type(length),dat ...

  2. #!/usr/bin/env bash和#!/usr/bin/bash的比较

    #!/usr/bin/env bash和#!/usr/bin/bash的比较 stackoverflow: http://stackoverflow.com/questions/16365130/th ...

  3. IIS短文件名漏洞复现

    IIS短文件名漏洞复现 一.漏洞描述 此漏洞实际是由HTTP请求中旧DOS 8.3名称约定(SFN)的代字符(~)波浪号引起的.它允许远程攻击者在Web根目录下公开文件和文件夹名称(不应该可被访问). ...

  4. python3键盘输入

    1.脚本 # -*- coding: utf-8 -*- print("今年是哪一年?"),year = input("年份:")print ("ji ...

  5. Ubuntu启动Apache

    划重点:最重要的是找到一个文件--------startup.sh 如果你是按照百度上的方法下载的Apache2,那么就按照百度的方式来 但是异曲同工 如果你是自己在网上下载的Apache到的磁盘 找 ...

  6. Python实现批量处理扫描特定目录

    ## 简述在渗透测试中遇到相同CMS站点时,搞定一个站点,相当于拿了一个站群的通用漏洞,所以我们首先需要标注站点的CMS类型,根据要求编写如下脚本 ## 要求1.访问特定目录,如:站点特定 /cmsa ...

  7. Spring的依赖注入和管理Bean

    采用Spring管理Bean和依赖注入 1.实例化spring容器 和 从容器获取Bean对象 实例化Spring容器常用的两种方式: 方法一: 在类路径下寻找配置文件来实例化容器 [推荐使用] Ap ...

  8. 一份新的lilypond谱子,能设置页边距和设置换页符了

    给学生做的一份乐谱,这回能设置页边距了,以及设置换页符了. 顺带能设置一些代码片段(snippet),可以用热键代替使用 设置页边距的snippet: \paper { %双引号里面填页面大小 #(s ...

  9. GBK和UTF-8的区别

    我们这里将以最简单最容易理解的方式来描述GBK和UTF8的区别,以及它们分别是什么.   GBK编码:是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符 ...

  10. docker 容器之间互联

    容器之间的互联 一. 实验目的: 1.       熟悉容器之间基本的网络原理: 2.       掌握容器之间互联的方法: 二. 实验环境: Ubuntu16.04+Docker 三. 实验内容: ...