Java中有一種特殊的線程叫做守護(Daemon)線程。這種線程的優先級很低,通常來說,當同一個應用程序里沒有其他的線程運作的時候,守護線程才運行。當守護線程是程序中唯一的線程時,守護線程執行結束后,JVM也就結束了這個程序。一個典型的守護線程是Java的垃圾回收器(Garbage Collector)。
示例程序如下:
1.創建Event類
import java.util.Date; 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; } }
2. 創建WriterTask類
import java.util.Date; import java.util.Deque; import java.util.concurrent.TimeUnit; public class WriterTask implements Runnable { private Deque<Event> deque; public WriterTask(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(String.format( "The thread %s has been generated an event", Thread .currentThread().getId())); deque.addFirst(event); // System.out.println("event: "+event.getDate()); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
3. 創建CleanerTask類
import java.util.Date; import java.util.Deque; import java.util.concurrent.TimeUnit; public class CleanerTask extends Thread { private Deque<Event> deque; public CleanerTask(Deque<Event> deque){ this.deque = deque; this.setDaemon(true); } @Override public void run() { while(true){ Date date = new Date(); clean(date); } } private void clean(Date date){ long diff; boolean delete; if(deque.isEmpty()) return; delete = false; do{ Event e = deque.getLast(); diff = date.getTime()-e.getDate().getTime(); if(diff>10000){ System.out.printf("Cleaner: %s\n", e.getEvent()); deque.removeLast(); delete = true; } }while(diff>10000&&!deque.isEmpty()); if(delete){ System.out.printf("Cleaner: Size of the queue: %d\n", deque.size()); } } }
4. 實現主類Main
import java.util.ArrayDeque; import java.util.Deque; public class Main { public static void main(String[] args) { Deque<Event> deque = new ArrayDeque<Event>(); WriterTask wt = new WriterTask(deque); //創建三個客戶端進程 for(int i=0;i<3;i++){ Thread t = new Thread(wt); t.start(); } //創建一個守護進程 CleanerTask ct = new CleanerTask(deque); ct.start(); } }
注:setDaemon()方法只能在start()方法被調用之前設置。一旦程序開始運行,將不能在修改守護狀態。