Java多线程编程之守护线程
Java的线程分为两种,一个是用户线程,一个是守护线程。守护线程守护的对象就是用户线程,当用户线程结束后,守护它的守护线程也就会结束。二者的本质基本是一样的,唯一区别在于何时结束。
- 用户线程:直到自己运行完或者遇到异常就结束
- 守护线程:生命周期伴随着用户线程,随着用户线程结束而结束。
举个例子:运行状态的日志线程一般为守护线程,它时时记录运行状态的日志,守护着系统的主线程。当主线程结束或出现异常结束后,记录日志的守护线程就没有必要在记录,随着主线程结束而结束。
在java中将用户线程变为守护线程,调用setDaemon方法。
package com.my.day01.demo05;
public class DaemoTest {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" running");
Thread.sleep(2000);
System.out.println("test");
System.out.println(Thread.currentThread().getName()+" done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//设置为非守护线程,随着main线程的结束,守护线程也结束
t.setDaemon(false);
t.start();
System.out.println(Thread.currentThread().getName());
}
}
结果为:
main
Thread-0 running
test
Thread-0 done
在这个例子中,线程t为非守护线程,那么在main线程执行完后,线程t仍在执行。从输出的结果就可以看出来。
将线程t设为守护线程再来看一下
package com.my.day01.demo05;
public class DaemoTest {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" running");
Thread.sleep(2000);
System.out.println("test");
System.out.println(Thread.currentThread().getName()+" done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//设置为守护线程,随着main线程的结束,守护线程也结束
t.setDaemon(true);
t.start();
System.out.println(Thread.currentThread().getName());
}
}
结果为:
main
Thread-0 running
将线程设置为守护线程后,可以看到线程t没有运行完毕就随着main线程的结束而结束了。
再来看嵌套线程的守护线程,在main函数里面声明了一个名字叫Thread1的线程,在Thread1线程里面定义了一个名字为Thread2的线程。先将这个两个线程设为非守护线程,看结果。
package com.my.day01.demo05;
public class DaemoTest2 {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Thread tt = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "running");
try {
Thread.sleep(20_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "done");
}
}, "Thread2");
tt.setDaemon(false);
tt.start();
System.out.println(Thread.currentThread().getName() + "running");
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "done");
}
}, "Thread1");
// 设置为非守护线程,随着main线程的结束,守护线程也结束
t.setDaemon(false);
t.start();
System.out.println(Thread.currentThread().getName());
}
}
结果:
main
Thread1running
Thread2running
Thread1done
Thread2done
main线程执行完后,Thread2和Thread1交替执行。再来看看将子线程Thread2设为守护线程,输出的结果为
main
Thread1running
Thread2running
Thread1done
可以看到子线程Thread2守护Thread1,当Thread1结束后,Thread2也随之结束。
如果将线程Thread1也设置为守护线程,再来看结果
main
Thread1守护的是main线程,main线程一结束Thread1也随之结束。Thread1的子线程Thread2也跟着结束(这就是说守护线程具有继承性,如果一个线程为守护线程,那么它的子线程都为守护线程)
总结:
1.守护线程守护的是它所在声明的那个线程。
2.当指定一个线程为守护线程后,它的子线程都是守护线程。
Java多线程编程之守护线程的更多相关文章
- java并发编程学习: 守护线程(Daemon Thread)
在正式理解这个概念前,先把 守护线程 与 守护进程 这二个极其相似的说法区分开,守护进程通常是为了防止某些应用因各种意外原因退出,而在后台独立运行的系统服务或应用程序. 比如:我们开发了一个邮件发送程 ...
- java 多线程8(守护线程)
比如:后台偷偷运行的那些,qq下载更新包 如果一个进程中只剩下了守护线程,那么守护线程也会死亡.. 一个线程默认都不是守护线程. 判断是否是守护线程:例:d.isDaemon(); 当一个线程随着你的 ...
- JAVA多线程学习六-守护线程
java中的守护程序线程是一个服务提供程序线程,它为用户线程提供服务. 它的生命依赖于用户线程,即当所有用户线程都死掉时,JVM会自动终止该线程. 有许多java守护程序线程自动运行,例如 gc,fi ...
- java多线程编程(二创建线程)
1.概念 因为java是完全面向对象的,所以在java中,我们说的线程,就是Thread类的一个实例对象.所以,一个线程就是一个对象,它有自己字段和方法. 2.创建线程 创建线程有 ...
- Java多线程编程(1)--Java中的线程
一.程序.进程和线程 程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码.它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编译之后生成的可执行文 ...
- Java多线程编程(4)--线程同步机制
一.锁 1.锁的概念 线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题.锁 ...
- 《java多线程编程核心技术》不使用等待通知机制 实现线程间通信的 疑问分析
不使用等待通知机制 实现线程间通信的 疑问分析 2018年04月03日 17:15:08 ayf 阅读数:33 编辑 <java多线程编程核心技术>一书第三章开头,有如下案例: ...
- Java多线程编程-线程之间的通信
转载自:这里 学习了基础的线程知识 看到了 线程之间的通信 线程之间有哪些通信方式呢? 1.同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. public ...
- Java—多线程编程
一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...
随机推荐
- 金币(0)<P2015_1>
金币 (coin.cpp/c/pas) [问题描述] 国王将金币作为工资,发放给忠诚的骑士.第一天,骑士收到一枚金币:之后两天(第二天和第三天),每天收到两枚金币:之后三天(第四.五.六天),每天收 ...
- scrapy 中 shell 出现 403 Forbiidden 解决方案
版权声明本文来自:https://blog.csdn.net/qq_37462361/article/details/87860025 进入正题: 出现 403,表示网站拒绝提供服务 (因为很多网站都 ...
- Keras下载的数据集以及预训练模型保存在哪里
Keras下载的数据集在以下目录中: root\\.keras\datasets Keras下载的预训练模型在以下目录中: root\\.keras\models 在win10系统来说,用户主目录是: ...
- c# 分页 PaginatedList<TResult>
using System; using System.Collections.Generic; using System.Linq; namespace Microestc.PaginatedList ...
- python笔记心得
1.字典的映射 day=10# def get_sunday():# return 'Sunday'# def get_monday():# return 'monday'# def get_tues ...
- SZWI3800
xml <mapper namespace="jp.co.alsok.g6.zwi.dao.mapper.g6.custom.SZWI3800Mapper"> < ...
- 吴裕雄--天生自然ORACLE数据库学习笔记:Oracle系统调优
--修改 alter system set large_pool_size=64m; --显示 show parameter large_pool_size; select sum(getmisses ...
- sparkRDD:第3节 RDD常用的算子操作
4. RDD编程API 4.1 RDD的算子分类 Transformation(转换):根据数据集创建一个新的数据集,计算后返回一个新RDD:例如:一个rdd进行map操作后生了一个新的rd ...
- 第1节 Scala基础语法:scala中的方法源码分析
val list=List(1,2,3,4) list.reduce((x:Int,y:Int)=>x+y)--->list.reduceLeft((x:Int,y:Int)=>x+ ...
- ls命令与cd命令
ls命令用于显示文件目录列表,当使用ls命令时,默认显示的只有非隐藏文件或文件夹(隐藏文件在linux中前面有 ' . ' ),当不加参数时,显示当前目录. 1.ls命令语法 ls [参数][目标文件 ...