守护进程,顾名思义就是默默在后台运行的进程,当JVM上没有其他进程运行时运行的进程,最典型的一个列子就是
JVM自带的垃圾清理机,他就是在其他程序不运行的时候占用CPU来进行清理内存垃圾,因此他具有很强的不确定性,
因为你不知道啥时候他就会运行,也不知道啥时候他不会运行,因此适合做一个不太重要的清理工作或者服务器上的监
听工作。
下面我们使用JVM的daemon来写一个小例子,实现的效果如下
In this recipe, we will learn how to create a daemon thread developing an example with two threads; one user thread that writes events on a queue and a daemon one that cleans that queue, removing the events which were generated more than 10 seconds ago。
这里的队列是一个双向列表。代码如下
package com.bird.concursey; import java.util.Date; import java.util.Deque; import java.util.concurrent.TimeUnit; public class WriterTask implements Runnable { public WriterTask(Deque<Event> deque) { this.deque = deque; } // 这个为双向队列 private Deque<Event> deque; public Deque<Event> getDeque() { return deque; } public void setDeque(Deque<Event> deque) { this.deque = deque; } @Override public void run() { for(int i = 0; i < 100; i++) { Event event = new Event(); event.setDate(new Date()); event.setEvent("The Thread " + Thread.currentThread().getId() + " has generated a event"); deque.addFirst(event); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package com.bird.concursey; import java.util.Date; import java.util.Deque; public class CleanerTask extends Thread { private Deque<Event> deque; public CleanerTask(Deque<Event> deque) { this.deque = deque; //设置为守护进程 setDaemon(true); } @Override public void run() { while(true) { Date date = new Date(); clean(date); } } private void clean(Date date) { long difference = 0; boolean delete = false; if(deque.size() == 0) { return; } do { Event e = deque.getLast(); difference = date.getTime() - e.getDate().getTime(); if(difference > 10000) { System.out.println("cleaner " + e.getEvent()); deque.removeLast(); delete = true; } }while(difference > 10000); if(delete) { System.out.println("cleaner : the size of the deque " + deque.size()); } } public Deque<Event> getDeque() { return deque; } public void setDeque(Deque<Event> deque) { this.deque = deque; } }
package com.bird.concursey; import java.util.ArrayDeque; import java.util.Date; import java.util.Deque; public class Event { private Date date; private String event; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getEvent() { return event; } public void setEvent(String event) { this.event = event; } public static void main(String[] args) { Deque<Event> deque = new ArrayDeque<Event>(); WriterTask writer = new WriterTask(deque); for(int i = 0; i < 3; i++) { Thread thread = new Thread(writer); thread.start(); } CleanerTask cleaner = new CleanerTask(deque); cleaner.start(); } }
cleaner The Thread 12 has generated a event cleaner The Thread 11 has generated a event cleaner : the size of the deque 27 cleaner The Thread 13 has generated a event cleaner : the size of the deque 26 cleaner The Thread 13 has generated a event cleaner The Thread 12 has generated a event cleaner The Thread 11 has generated a event cleaner : the size of the deque 26 cleaner The Thread 12 has generated a e
程就会占用CPU time 来运行清理建立好的事件,这样就会让队列一直维护在25-30左右,最关键的一句
//设置为守护进程 setDaemon(true);必须在start之前设置,因为线程一旦运行起来了就不能更改他的状态,这样就开
始了监控的状态,守护进程就OK了