Java里有一种特殊的线程叫做守护(Daemon)线程,这种线程的优先级很低,通常来说,当一个应用程序里面没有其他线程运行的时候,守护线程才运行,当线程是程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个程序。因此,守护线程通常被用来作为同一程序中普通线程的服务提供者,通常是无线循环的,以等待服务请求或者线程任务。

  代码实现

  1:创建Event类,声明两个私有属性

  

package com.packtpub.java7.concurrency.chapter1.recipe7.event;

import java.util.Date;

/**
* Class that stores event's information
*
*/
public class Event { /**
* Date of the event
*/
private Date date; /**
* Message of the event
*/
private String event; /**
* Reads the Date of the event
* @return the Date of the event
*/
public Date getDate() {
return date;
} /**
* Writes the Date of the event
* @param date the date of the event
*/
public void setDate(Date date) {
this.date = date;
} /**
* Reads the message of the event
* @return the message of the event
*/
public String getEvent() {
return event;
} /**
* Writes the message of the event
* @param event the message of the event
*/
public void setEvent(String event) {
this.event = event;
}
}

  2:创建WirterTask类,实现Runnable接口,声明一个存放Event对象的队列,并实现一个带参数的构造器,初始化这个队列,实现线程的run()方法,执行循环100次,每次循环中都会创建一个新的Event对象,并放入队列中,然后休眠1秒钟

package com.packtpub.java7.concurrency.chapter1.recipe7.task;

import java.util.Date;
import java.util.Deque;
import java.util.concurrent.TimeUnit; import com.packtpub.java7.concurrency.chapter1.recipe7.event.Event; /**
* Runnable class that generates and event every second
*
*/
public class WriterTask implements Runnable { /**
* Data structure to stores the events
*/
Deque<Event> deque; /**
* Constructor of the class
* @param deque data structure that stores the event
*/
public WriterTask (Deque<Event> deque){
this.deque=deque;
} /**
* Main class of the Runnable
*/
@Override
public void run() { // Writes 100 events
for (int i=1; i<100; i++) {
// Creates and initializes the Event objects
Event event=new Event();
event.setDate(new Date());
event.setEvent(String.format("The thread %s has generated an event",Thread.currentThread().getId())); // Add to the data structure
deque.addFirst(event);
try {
// Sleeps during one second
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

  3 创建CleanerTask类,并继承Thread类,声明存放Event对象的队列,也实现一个带参数的构造器,来初始化这个队列,在这个构造器中用setDaemon()方法,把这个线程设为守护线程。实现run()方法,他将无线的重复运行,并在每次运行中,取当前时间,调用clean()方法。实现clean()方法,读取队列的最后一个事件对象,如果这个事件是10s钟之前创建的,将他删除并且检查下一个,如果有时间被删除,clean()将打印出删除事件的信息,

package com.packtpub.java7.concurrency.chapter1.recipe7.task;

import java.util.Date;
import java.util.Deque; import com.packtpub.java7.concurrency.chapter1.recipe7.event.Event; /**
* Class that review the Event data structure and delete
* the events older than ten seconds
*
*/
public class CleanerTask extends Thread { /**
* Data structure that stores events
*/
private Deque<Event> deque; /**
* Constructor of the class
* @param deque data structure that stores events
*/
public CleanerTask(Deque<Event> deque) {
this.deque = deque;
// Establish that this is a Daemon Thread
setDaemon(true);
} /**
* Main method of the class
*/
@Override
public void run() {
while (true) {
Date date = new Date();
clean(date);
}
} /**
* Method that review the Events data structure and delete
* the events older than ten seconds
* @param date
*/
private void clean(Date date) {
long difference;
boolean delete; if (deque.size()==0) {
return;
} delete=false;
do {
Event e = deque.getLast();
difference = date.getTime() - e.getDate().getTime();
if (difference > 10000) {
System.out.printf("Cleaner: %s\n",e.getEvent());
deque.removeLast();
delete=true;
}
} while (difference > 10000);
if (delete){
System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());
}
}
}

  

  4:实现主类

  

public class Main {

    /**
* Main method of the example. Creates three WriterTasks and a CleanerTask
* @param args
*/
public static void main(String[] args) { // Creates the Event data structure
Deque<Event> deque=new ArrayDeque<Event>(); // Creates the three WriterTask and starts them
WriterTask writer=new WriterTask(deque);
for (int i=0; i<3; i++){
Thread thread=new Thread(writer);
thread.start();
} // Creates a cleaner task and starts them
CleanerTask cleaner=new CleanerTask(deque);
cleaner.start(); } }

  打印结果

Cleaner: Size of the queue: 28
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 11 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 10 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 11 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 10 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 11 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 10 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28

我们会发现,队列中的对象会不断增长至30个,然后程序结束,队列的长度维持在27-30之间,这个程序有3个WriteTask线程,每个线程向队列写入一个事件,然后休眠1秒钟,在第一个10s中,队列中有30个事件,直到3个WriterTask都结束后,CleanTask才开始执行,但是他没有删除任何事件,因为所有的事件都小于10秒钟,在接下来运行中,CleanTask每秒钟删除3个事件,同时WriteTask会写入3个对象,所以队列一直在27-30之间。

  

  

  

Java7并发编程实战(一) 守护线程的创建和运行的更多相关文章

  1. [笔记][Java7并发编程实战手冊]系列文件夹

    推荐学习多线程之前要看的书. [笔记][思维导图]读深入理解JAVA内存模型整理的思维导图文章里面的思维导图或则相应的书籍.去看一遍. 能理解为什么并发编程就会出现故障. Java7并发编程实战手冊 ...

  2. 《Java7并发编程实战手册》读书笔记

    一.线程管理 1.线程的创建和运行 创建线程的2种方式: 继承Thread类,并覆盖run()方法 创建一个实现Runnable接口的类.使用带参数的Thread构造器来创建Thread对象 每个Ja ...

  3. [笔记][Java7并发编程实战手冊]3.8 并发任务间的数据交换Exchanger

    [笔记][Java7并发编程实战手冊]系列文件夹 简单介绍 Exchanger 是一个同步辅助类.用于两个并发线程之间在一个同步点进行数据交换. 同意两个线程在某一个点进行数据交换. 本章exchan ...

  4. [笔记][Java7并发编程实战手冊]3.4 等待多个并发事件的完毕CountDownLatch倒计数闭锁

    [笔记][Java7并发编程实战手冊]系列文件夹 简单介绍 本文学习CountDownLatch 倒计数闭锁. 本人英文不好.靠机器翻译,然后有一段非常形象的描写叙述,让我把它叫为倒计数 用给定的计数 ...

  5. 【JAVA并发第二篇】Java线程的创建与运行,线程状态与常用方法

    1.线程的创建与运行 (1).继承或直接使用Thread类 继承Thread类创建线程: /** * 主类 */ public class ThreadTest { public static voi ...

  6. Java7并发编程实战(一) 线程的管理

    1:线程的创建   1:继承Thread类,并且覆盖run()方法  2:创建一个实现Runnable接口的类.使用带参数的Thread构造器来构造 2:example-->计算打印乘法表 首先 ...

  7. 【Java并发编程】:守护线程与线程阻塞的四种情况

    守护线程 JAVA中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运 ...

  8. 漫谈并发编程(二):java线程的创建与基本控制

    java线程的创建 定义任务           在java中使用任务这个名词来表示一个线程控制流的代码段,用Runnable接口来标记一个任务,该接口的run方法为线程运行的代码段. public ...

  9. Java7并发编程实战(一) 线程的等待

    试想一个情景,有两个线程同时工作,还有主线程,一个线程负责初始化网络,一个线程负责初始化资源,然后需要两个线程都执行完毕后,才能执行主线程 首先创建一个初始化资源的线程 public class Da ...

随机推荐

  1. 【AdaBoost算法】弱分类器训练过程

    一.加载数据(正样本.负样本特征) def loadSimpData(): #样本特征 datMat = matrix([[ 1. , 2.1, 0.3], [ 2. , 1.1, 0.4], [ 1 ...

  2. Flume应用场景及架构原理

    Flume概念 Flume是一个分布式.可靠.和高可用的海量日志聚合的系统,支持在系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力. ...

  3. javascript-适配器模式

    适配器模式笔记 将一个类(对象)的接口(方法或属性)转化成另一个接口,以满足用户需求,使类(对象)之间接口的不兼容性问题通过适配器方法得以解决 demo实例:1.适配参数对象,使传入的参数完整 2.适 ...

  4. maven 安装alipay-sdk包到本地及远程仓库

    安装到本地:mvn install:install-file -DgroupId=com.alipay -DartifactId=sdk-Java -Dversion=*** -Dpackaging= ...

  5. html5+css3实现跑动的爱心/动态水滴效果[原创][5+3时代]

    大风起兮云飞扬,安得猛士兮走四方!html5+css3,不学不行. 做web开发已经有好几年了,见证了太多语言的崛起和陨落. 其实作为一个程序员最苦逼的事情莫过于每天要不停的追赶各大公司新出的框架和语 ...

  6. pt-diskstats 报错 Can't locate Time/HiRes.pm in @INC

    调用 pt-diskstats 时报错如下Can't locate Time/HiRes.pm in @INC [root@localhost ~]# pt-diskstats Can't locat ...

  7. MySQL 命令行工具之 mysqldump 深入研究

    mysqldump 是MySQL的一个命令行工具,用于逻辑备份.可以将数据库和表的结构,以及表中的数据分别导出成:create database, create table, insert into的 ...

  8. shell将标准错误输出重定向到 其他地方

    经常可以在一些脚本,尤其是在crontab调用时发现如下形式的命令调用: /tmp/test.sh > /tmp/test.log >& 前半部分/tmp/test.sh > ...

  9. 烂泥:使KVM显示VM的IP地址及主机名

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. KVM虚拟化学习已经有一段时间了,现在虚拟化软件比较多,对比了下目前使用比较多的VMware Vsphere.发现在不进入VM系统的情况下,Vspher ...

  10. iOS UIScrollView 无法滚动 没有弹簧效果解决方案

    一般情况下,检查如下: 1.没有设置contentSize或者contentSize的尺寸小于等于该scrollView的尺寸 2.scrollView.enable = NO;(仅仅是让scroll ...