qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          守護線程

           在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()) != nullreturn 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 = new File("c:/blacklist.txt");
          12    
          13    public void init() throws Exception{
          14        loadConfig();
          15        ConfigWatchDog dog = new ConfigWatchDog();
          16        dog.setName("daemon_demo_config_watchdog");//a
          17        dog.addFile(configFile);//b
          18        dog.start();//c
          19    }

          20    
          21    public void loadConfig(){
          22        try{
          23            Thread.sleep(1*1000);//d
          24        
          25            System.out.println("加載黑名單");
          26        }
          catch(InterruptedException ex){
          27            System.out.println("加載配置文件失敗!");
          28        }

          29    }

          30        
          31    public File getConfigFile() {
          32        return configFile;
          33    }

          34
          35    public void setConfigFile(File configFile) {
          36        this.configFile = configFile;
          37    }

          38
          39
          40    private class ConfigWatchDog extends FileWatchdog{
          41        
          42        @Override
          43        protected void doOnChange(File file) {
          44            System.out.println("文件"+file.getName()+"發生改變,重新加載");
          45            loadConfig();
          46        }

          47        
          48    }

          49    
          50    public static void main(String[] args) throws Exception {
          51        BlacklistService service = new BlacklistService();
          52        service.init();
          53        
          54        Thread.sleep(60*60*1000);//e
          55    }

          56}

          57

                  ConfigWatchDog內部類實現了doOnChange(File file)方法,當文件被修改后,watchdog調用doOnChange方法完成重新加載操作;
                  在blackservice的init方法中初始化watchdog線程;
                  d:模擬文件加載耗時
                  e:主要是防止主線程退出;

                  其實上面的FileWatchdog就是取自log4j;
                  

          posted on 2011-09-21 23:29 順其自然EVO 閱讀(553) 評論(0)  編輯  收藏

          <2011年9月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 三穗县| 溆浦县| 宽城| 根河市| 睢宁县| 红桥区| 寿光市| 神木县| 宁国市| 清苑县| 黔江区| 成安县| 安远县| 蚌埠市| 彭州市| 宝鸡市| 水富县| 昭平县| 临洮县| 宁乡县| 新乡市| 进贤县| 勃利县| 凉城县| 浪卡子县| 海丰县| 东台市| 香河县| 台南县| 威信县| 即墨市| 台东县| 屏南县| 西畴县| 晋城| 潼南县| 屯留县| 枞阳县| 萍乡市| 平顶山市| 稻城县|