文档章节

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

pan_1308
 pan_1308
发布于 2017/09/05 16:10
字数 1564
阅读 8
收藏 1
点赞 0
评论 0

一、概述

当一个应用程序里没有其他的线程运行的时候,守护线程才运行;当守护线程是程序中唯一运行的线程时,守护线程执行结束后,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
粉丝 4
博文 93
码字总数 58819
作品 0
黄冈
[转载] Java多线程编程总结

今天偶然看到一篇关于Java多线程的精品文章,实在是“爱不释手”,遂转载下来,以供大家参考: [Java多线程编程总结](转自:http://lavasoft.blog.51cto.com/62575/27069) 一、认识多任务、...

晨曦之光
2012/03/09
0
0
Java Thread及其synchronized,wait,sleep,join,yeid,interrupt

Java SE7 API - Thread: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield%28%29 参考资料:http://blog.csdn.net/lqqmisslll/article/details/54208491 一、线程的简......

YuanyuanL
2015/08/12
0
0
java基础thread——多线程的纷争(循序渐进)

一、多线程概述 进程: 正在运行的程序,是系统进行资源分配和调用的独立单位。 每一个进程都有它自己的内存空间和系统资源。 多进程有什么意义呢? 单进程的计算机只能做一件事情,而我们现在...

潇潇漓燃
05/30
0
0
JAVA多线程和并发基础面试问答

原文链接 译文连接 作者:Pankaj 译者:郑旭东 校对:方腾飞 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢...

雷神雨石
2014/07/19
0
2
JAVA多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:...

LCZ777
2014/05/26
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

清风傲剑
2014/12/06
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

hanzhankang
2014/01/20
0
0
Java高级-解析Java中的多线程机制

一、进程与应用程序的区别 进程(Process)是最初定义在Unix等多用户、多任务操作系统环境下用于表示应用程序在内存环境中基本执行单元的概念。以Unix操作系统为例,进程是Unix操作系统环境中...

陶邦仁
2012/11/11
0
0
Java 对象锁-synchronized()与线程的状态与生命周期与守护进程

synchronized(someObject){ //对象锁} 一、对象锁 someObject 的使用说明: 1、对象锁的返还。 当synchronize()语句执行完成。 当synchronize()语句执行出现异常。 当线程调用了wait()方法。...

Oscarfff
2015/05/04
0
0
《深入Java虚拟机》——Java虚拟机读书笔记

1、Java虚拟机的生命周期 如果在同一台计算机上同时运行三个Java程序,将得到三个Java虚拟机实例。 在Java虚拟机内部有两种线程,守护线程和非守护线程。守护线程通常是由虚拟机自己使用的,...

亭子happy
2014/04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

CentoOS6.6安装netcat

CentOS下安装netcat 使用zookeeper过程中,需要监控集群状态。在使用四字命令时(echo conf | nc localhost 2181),报出如下错误:-bash: netcat: command not found。 我的系统是CentOS 6....

ghou-靠墙哭
8分钟前
0
0
es6之解构赋值巧用

ES6 允许按照一定模式,从数组、对象等中提取值,对变量进行赋值,这被称为解构赋值。 如何进行解构赋值我这里就不赘述,本篇文章主要是将解构赋值的巧妙使用之处。 1、交互变量的值 常用交互...

秋季长青
13分钟前
0
0
Elasitcsearch High Level Rest Client学习笔记(三)批量api

Bulk Request BulkRequest可以在一起从请求执行批量添加、更新和删除,至少需要添加一个操作 BulkRequest request = new BulkRequest(); //创建BulkRequestrequest.add(new IndexRequest("...

木子SMZ
16分钟前
0
0
mybatis-dynamic sql

OGNL expressions if 判断是否存在值 <select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{tit......

writeademo
24分钟前
0
0
社交系统ThinkSNS+ V1.8.3更新播报

     研发发布版本号:1.8.3   本次版本于2018年7月16日发布   本次发布类型:新增功能、细节调整与优化   社交系统ThinkSNSPlus更新体验:请于官网下载/安装最新版或联系QQ35159...

ThinkSNS账号
27分钟前
0
0
教育思考:选择编程是一场父母和孩子的和解[图]

教育思考:选择编程是一场父母和孩子的和解[图]: 之前有个很热的段子是这样讲的:深夜十点的时候,某小区一女子大声喊叫“什么关系?啊?!到底什么关系?你说!”最后发现原来是一位妈妈陪...

原创小博客
28分钟前
0
0
X64汇编之指令格式解析

最近由于项目组内要做特征码搜索的东西,便于去Hook一些未导出函数,你懂得...于是就闲着学习了一下x86/x64的汇编指令格式。x86的汇编指令格式请参照http://bbs.pediy.com/showthread.php?t...

simpower
31分钟前
0
0
rust 语法概要(只适合不熟悉时快速查阅使用,不适合理解其精髓。未完待续)

注意:本内容只适合快查,不适合理解精髓。精髓请研读 https://kaisery.github.io/trpl-zh-cn/foreword.html 基本数据类型 i8,i16,i32,i64,i128 u8,u16,u32,u64,u128 f32,f64 char bool:true...

捍卫机密
34分钟前
0
0
JS中严格模式和非严格模式

1,使用 严格模式的使用很简单,只有在代码首部加入字符串 "use strict"。必须在首部即首部指其前面没有任何有效js代码除注释,否则无效 2.注意事项 (1)不使用var声明变量严格模式中将不通...

AndyZhouX
34分钟前
0
0
Nginx配置error_page 404 500等自定义的错误页面

Nginx 做web server时, 开发中发现有时候的网站代码有错误,我们需要跳转到一个指定内容的错误页面: 1. 在nginx.conf配置文件上加上一句: fastcgi_intercept_errors on; 2. 服务中加上: er...

MichaelShu
36分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部