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 ",e.getEvent()); deque.removeLast(); delete=true; } } while (difference > 10000); if (delete){ System.out.printf("Cleaner: Size of the queue: %d ",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之间。