探索java多線程(連載)1 守護線程 – JAVA編程語言程序開發技術文章

 在java中有一類線程,專門在後臺提供服務,此類線程無需顯式關閉,當程序結束瞭,它也就結束瞭,這就是守護線程 daemon thread。如果還有非守護線程的線程在執行,它就不會結束。      守護線程有何用處呢?讓我們來看個實踐中的例子。


      在我們的系統中經常應用各種配置文件(黑名單,禁用詞匯),當修改配置文件後,一般要重啟服務,系統才能夠加載;當重啟服務的代價比較高的情況下,這種加載方式不能滿足我們的要求,這個時候守護線程該發揮它的作用瞭,它可以實時加載你的配置文件,無需重啟。(當然,相當重要的配置文件,不推薦實時加載)


 


package com.ikon.thread.daemon;


import java.io.File;
import java.util.*;


/** *//**
 * 文件監測
 * @author ikon99999
 *
 */
public abstract class FileWatchdog extends Thread {


 
  static final public long DEFAULT_DELAY = 20*1000;
 
 
  protected HashMap fileList;
 
  protected long delay = DEFAULT_DELAY;
 
  boolean warnedAlready = false;
 
  boolean interrupted = false;


  public static class Entity
  {
        File file;
        long lastModify;
        Entity(File file,long lastModify)
        {
            this.file = file;
            this.lastModify = lastModify;
        }
  }
 
  protected  FileWatchdog() {
      fileList = new HashMap ();
    setDaemon(true);
  }


 
  public  void setDelay(long delay) {
    this.delay = delay;
  }


  public void addFile(File file)
  {
        fileList.put(file.getAbsolutePath(),new Entity(file,file.lastModified()));    
  }
 
  public boolean contains(File file)
  {
        if( fileList.get(file.getAbsolutePath()) != null) return true;
        else return false;
  }
 
  abstract   protected   void doOnChange(File file);


  protected  void checkAndConfigure() {
      HashMap map = (HashMap)fileList.clone();
      Iterator it = map.values().iterator();
     
      while( it.hasNext())
      {
         
            Entity entity = (Entity)it.next();
           
            boolean fileExists;
            try {
              fileExists = entity.file.exists();
            } catch(SecurityException  e)
            {
              System.err.println (“Was not allowed to read check file existance, file:[“+ entity.file .getAbsolutePath() +”].”);
              interrupted = true;
              return;
            }


            if(fileExists)
            {
               
              long l = entity.file.lastModified(); // this can also throw a SecurityException
              if(l > entity.lastModify) {           // however, if we reached this point this
                    entity.lastModify = l;              // is very unlikely.
                    newThread(entity.file);
              }
            }
            else
            {
                System.err.println (“[“+entity.file .getAbsolutePath()+”] does not exist.”);
            }
      }
  }
 
  private void newThread(File file)
  {
      class MyThread extends Thread
      {
            File f;
            public MyThread(File f)
            {
                this.f = f;
            }
           
            public void run()
            {
                doOnChange(f);
            }
      }
     
      MyThread mt = new MyThread(file);
      mt.start();
  }


  public  void run()
  {   
    while(!interrupted) {
      try {
        Thread.currentThread().sleep(delay);
      } catch(InterruptedException e) {
    // no interruption expected
      }
      checkAndConfigure();
    }
  }
}


    FileWatchdog是個抽象類,本身是線程的子類;在構造函數中設置為守護線程;
    此類用hashmap維護著一個文件和最新修改時間值對,checkAndConfigure()方法用來檢測哪些文件的修改時間更新瞭,如果發現文件更新瞭則調用doOnChange方法來完成監測邏輯;doOnChange方法是我們需要實現的;看下面關於一個黑名單服務的監測服務:
      


 1package com.ikon.thread.daemon;
 2
 3import java.io.File;
 4
 5/** *//**
 6 * 黑名單服務
 7 * @author ikon99999
 8 * 2011-3-21
 9 */
10public class BlacklistService {
11    private File configFile

發佈留言