文档章节

Java 多线程 - 线程 - 守护线程

pan_1308
 pan_1308
发布于 2017/09/05 16:10
字数 1564
阅读 30
收藏 1

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

一、概述

当一个应用程序里没有其他的线程运行的时候,守护线程才运行;当守护线程是程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个程序。

基于以上特性,守护线程通常被用来作为同一程序中普通线程(也称之为用户线程)的服务提供者。它们通常是无限循环的,以等待服务请求或者执行线程的任务。它们不能做重要的工作,因为不可能知道守护线程什么时候能够获取 cpu 时钟,并且,在没有其他线程运行的时候,守护线程随时可能结束。典型的守护线程 Java 的垃圾回收器。

注意:

1、setDaemon() 方法只能在 start() 方法被调用之前设置;一旦线程开始运行,将不能再修改守护状态;

2、isDaemon() 方法被用来检查一个线程是否是守护线程,返回 true 表示守护线程,false 表示 这个线程是 用户线程;

二、实现

示例:  创建2个线程:一个是用户线程,它将事件写入到一个队列中;另外一个是守护线程,它将管理这个队列,如果生成的事件超过 10 秒钟,该事件就会被删除。

import java.util.Date;

/**
 * 自定义事件
 */
public class MyEvent {
    public static int globalI = 0;
	public int id;
	private String name;
	private Date createTime;
	
	public MyEvent(){
		modifyI();
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String toString() {
		return "MyEvent [id=" + id + ", name=" + name + ", createTime="
				+ createTime + "]";
	}
	
	// 创建唯一编号的事件.
	public synchronized void modifyI(){
		id =  ++globalI;
		setId(id);
	}
}
import java.util.Date;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

/**
 * 向队列中放入待处理的事件
 */
public class WriterTask implements Runnable{

	private Queue<MyEvent> queue;
	
	public WriterTask(Queue<MyEvent> queue){
		this.queue = queue;
	}
	
	public void run() {
		if(queue == null){
			System.out.println("添加操作-存放的 queue队列 未能初始化...");
		}
		for(int i=0;i<3;i++){
			MyEvent myEvent = new MyEvent();
			myEvent.setName("name_" +i);
			myEvent.setCreateTime(new Date());
			queue.add(myEvent);
			System.out.println(Thread.currentThread().getName() + "添加一个待处理事件:" + myEvent);
			try {
				TimeUnit.SECONDS.sleep(1); //休眠1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
			System.out.println(Thread.currentThread().getName() + ":现有 queue中的事件数为:" + queue.size());
		}
	}
}
import java.util.Date;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

/***
 *  清理 queue 队列中的 待处理事件.
 */
public class CleanTesk extends Thread{

	private Queue<MyEvent> queue;
	public CleanTesk(Queue<MyEvent> queue){
		this.queue = queue;
	    setDaemon(true); // 设置为 守护线程 - 此方法是 Thread类中的
	}
	
	public void run() {
		if (queue == null) {
			System.out.println("清理操作-存放的 queue队列 未能初始化...");
		}
		while(true){
			Date date = new Date();
			clean(date);
		}
	}

	// 清理操作
	public void clean(Date date){
		boolean isDelete = false;
		if(queue.size() == 0){
			System.out.println("清理操作-存放的 queue队列 没有待处理的事件...");
			try {
				TimeUnit.SECONDS.sleep(10); //10s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		    return;
		}
		MyEvent myEvent = queue.poll();
		if(myEvent == null){
			System.out.println("清理操作-获取待处理的事件无效...");
			return;
		}
		long difference = date.getTime() - myEvent.getCreateTime().getTime();
		if(difference >= 10000){ // 10s
		    isDelete = true;
		}else{ // 时间不够,再放回去
			queue.add(myEvent);
		}
		if(isDelete){
			System.out.println(Thread.currentThread().getName()+"-清理了 一个待处理任务...myevent:"+myEvent);
			try {
				TimeUnit.SECONDS.sleep(1); //休息1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
			System.out.println(Thread.currentThread().getName()+"-还剩的待处理任务...queue:"+queue.size());
		}
	}
}
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 守护线程测试
 */
public class DaemonTest {

  public static void main(String[] args) {
	  Queue<MyEvent> queue = new LinkedBlockingQueue<MyEvent>();
	  WriterTask writerTask = new WriterTask(queue);
	  for(int i=0;i<3;i++){
		  Thread thread = new Thread(writerTask);
		  thread.start();
	  }
	
	  CleanTesk cleanTesk = new CleanTesk(queue);
	  Thread clearThread = new Thread(cleanTesk);
	  clearThread.start();
  }	
}
//console打印结果:
清理操作-存放的 queue队列 没有待处理的事件...
Thread-1添加一个待处理事件:MyEvent [id=1, name=name_0, createTime=Tue Sep 05 16:02:01 CST 2017]
Thread-0添加一个待处理事件:MyEvent [id=2, name=name_0, createTime=Tue Sep 05 16:02:01 CST 2017]
Thread-2添加一个待处理事件:MyEvent [id=3, name=name_0, createTime=Tue Sep 05 16:02:01 CST 2017]
Thread-0:现有 queue中的事件数为:3
Thread-2:现有 queue中的事件数为:3
Thread-0添加一个待处理事件:MyEvent [id=4, name=name_1, createTime=Tue Sep 05 16:02:02 CST 2017]
Thread-1:现有 queue中的事件数为:3
Thread-2添加一个待处理事件:MyEvent [id=5, name=name_1, createTime=Tue Sep 05 16:02:02 CST 2017]
Thread-1添加一个待处理事件:MyEvent [id=6, name=name_1, createTime=Tue Sep 05 16:02:02 CST 2017]
Thread-0:现有 queue中的事件数为:6
Thread-2:现有 queue中的事件数为:6
Thread-0添加一个待处理事件:MyEvent [id=7, name=name_2, createTime=Tue Sep 05 16:02:03 CST 2017]
Thread-2添加一个待处理事件:MyEvent [id=8, name=name_2, createTime=Tue Sep 05 16:02:03 CST 2017]
Thread-1:现有 queue中的事件数为:8
Thread-1添加一个待处理事件:MyEvent [id=9, name=name_2, createTime=Tue Sep 05 16:02:03 CST 2017]
Thread-0:现有 queue中的事件数为:9
Thread-1:现有 queue中的事件数为:9
Thread-2:现有 queue中的事件数为:9
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=1, name=name_0, createTime=Tue Sep 05 16:02:01 CST 2017]
Thread-4-还剩的待处理任务...queue:8
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=2, name=name_0, createTime=Tue Sep 05 16:02:01 CST 2017]
Thread-4-还剩的待处理任务...queue:7
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=3, name=name_0, createTime=Tue Sep 05 16:02:01 CST 2017]
Thread-4-还剩的待处理任务...queue:6
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=4, name=name_1, createTime=Tue Sep 05 16:02:02 CST 2017]
Thread-4-还剩的待处理任务...queue:5
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=5, name=name_1, createTime=Tue Sep 05 16:02:02 CST 2017]
Thread-4-还剩的待处理任务...queue:4
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=6, name=name_1, createTime=Tue Sep 05 16:02:02 CST 2017]
Thread-4-还剩的待处理任务...queue:3
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=7, name=name_2, createTime=Tue Sep 05 16:02:03 CST 2017]
Thread-4-还剩的待处理任务...queue:2
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=8, name=name_2, createTime=Tue Sep 05 16:02:03 CST 2017]
Thread-4-还剩的待处理任务...queue:1
Thread-4-清理了 一个待处理任务...myevent:MyEvent [id=9, name=name_2, createTime=Tue Sep 05 16:02:03 CST 2017]
Thread-4-还剩的待处理任务...queue:0
清理操作-存放的 queue队列 没有待处理的事件...

 

© 著作权归作者所有

pan_1308
粉丝 5
博文 95
码字总数 58819
作品 0
黄冈
私信 提问
加载中

评论(0)

志玲姐姐已经找到了自己的守护天使,你呢?

多线程一直是我们开发中最关注的一个点,因为在并发中,会有各种各样的问题,但是这中多线程中的问题,又是我们需要去解决的,之前看书看到过一点内容,也和大家分享一下关于守护线程的一些知...

osc_ai011l20
2019/08/04
1
0
面试官: 谈谈什么是守护线程以及作用 ?

文章首发自微信公众号: 小哈学Java 个人网站: https://www.exception.site/java-concurrency/java-concurrency-daemon-thread 目录 一、什么是守护线程 二、守护线程的作用及应用场景 三、总...

osc_msepeizi
04/16
19
0
Java多线程编程(1)--Java中的线程

一.程序、进程和线程   程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码。它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编...

osc_odfa308v
2019/08/29
8
0
20165326 java第八周学习笔记

第八周学习笔记 知识点总结 1、进程与线程 进程:程序的一次动态执行过程 区别:进程和线程的区别? 进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元 同一个进程中可以包括...

osc_x4wridbb
2018/04/22
1
0
20200225 Java 多线程(1)-廖雪峰

Java 多线程(1)-廖雪峰 多线程基础 进程和线程的关系就是:一个进程可以包含一个或多个线程,但至少会有一个线程。 操作系统调度的最小任务单位其实不是进程,而是线程。常用的Windows、L...

osc_jqntvyw1
02/25
7
0

没有更多内容

加载失败,请刷新页面

加载更多

Python笔记:记pandas中几个好用的函数

pandas是python数据分析常用的库之一!从数据加载到预处理,从数据分析到可视化,pandas提供了一站式服务。而以下这几个聚合统计函数,更是好用! 本文主要讲解pandas中的7个聚合统计相关函数...

tengyulong
32分钟前
17
0
使用“ let”和“ var”有什么区别? - What's the difference between using “let” and “var”?

问题: ECMAScript 6 introduced the let statement . ECMAScript 6引入了let语句 。 I've heard it that it's described as a "local" variable, but I'm still not quite sure how it beh......

javail
今天
17
0
如何将文件重置或还原到特定版本? - How can I reset or revert a file to a specific revision?

问题: I have made some changes to a file which has been committed a few times as part of a group of files, but now want to reset/revert the changes on it back to a previous ver......

fyin1314
今天
24
0
OSChina 周五乱弹 —— 头发和不要头发,你总要选一个

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《雾 缀じた街 ふたつのかげ》- Porkkana 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
49
0
一道 算法题 引发的 ‘xx现场’

请 熟悉的语言 去 验证 在输入框中输入的是否是一个正确的网址 初次读题萌新有点 不知所措的样子一查 MDN 吓一跳 ----- 一个不怎么熟悉的方法跳出眼边URL() 构造函数返回一个新创建的 ...

酒窝yun过去了
今天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部