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;
}
}
View Code
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();
}
}
}
}
View Code
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());
}
}
}
View Code
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之间。