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. CMPP3.0 长短信实现方案

    长短信息:是指超过70个汉字,140个字节的信息内容 一.CMPP协议相关字段分析 CMPP协议具体部分请参考<中国移动互联网短信网关接口协议(V3.0.0).doc> CMPP_SUBM ...

  2. phonegap学习笔记

    [windows下安装] 1 先安装node.js: http://nodejs.org/ 2 CMD下运行: C:\> npm install -g phonegap [创建项目] CMD下运 ...

  3. C#语句1:选择语句一(if else )

    语句是指程序命令,都是按照顺序执行的.语句在程序中的执行顺序称为“控制流”或“执行流”. 根据程序对运行时所收到的输入的响应,在程序每次运行时控制流可能有所不同. 注意,语句间的标点符号必须是英文标点 ...

  4. hibernate 实现分页查询语句、单条查询语句、多条查询语句、修改、删除语句

    package com.hanqi.test; import java.util.Date; import java.util.List; import org.hibernate.Query; im ...

  5. iOS基于MBProgressHUD的二次封装,一行搞定,使用超简单

    MBProgressHUD的使用,临时总结了几款最常用的使用场景: 1.提示消息 用法: [YJProgressHUD showMessage:@"显示文字,1s隐藏" inVie ...

  6. my_strstr()

    const char* my_strstr(const char* S1,const char* S2){ int i=0,flag=0; while('\0'!=*(S1+i)){ if(*(S1+ ...

  7. 如何让django方法自动地定期执行

    实现思路:1.首先把需要自动执行的django method写成django command2.将自己定义的django command添加到cron中使用cron服务实现定期执行 Part1 在dj ...

  8. 谁在死锁Mutex——用Windbg查找Mutex死锁所有者线程

    Who is blocking that Mutex? - Fun with WinDbg, CDB and KD 05 Aug 2006 By Ingo Rammer I'm currently t ...

  9. PHP_Bibel阅读学习(一)——看书看经典,写文写代码

    基础快速再看一下,然后每天有新的好玩的看. 这本书,反正好评不少,就是`PHP和MySQL Web开发`,机械工业出版社,澳洲人写的,红皮,有兴趣的可以看一下. 第一篇 使用PHP 一.入门 5分钟翻 ...

  10. codevs哈希水题

    1230 多重hash练习一下,不用也可以 // // main.cpp // codeves1230 // // Created by Candy on 9/29/16. // Copyright ...