首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 定時任務與類熱加載實現文件變更監測

     編輯:Java 相關知識

需求場景

需在指定時間間隔內檢測某文件是否被修改,若修改則重新加載。本文提供三種實現方案:定時器輪詢、自定義類加載器熱加載、獨立線程睡眠檢查。

方案一:Timer 定時器輪詢

private Timer timer;

public void scheduleCheck(long delay, long period) {
    timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            // 你的業務邏輯:檢查文件最後修改時間
            System.out.println(System.currentTimeMillis());
        }
    }, delay, period);
}

優點:簡單易用,JDK 內置。
缺點:單線程串行,任務耗時長會影響下次執行;異常會導致定時器終止。

方案二:自定義類加載器實現熱加載

核心思路:監聽類文件修改時間,變更時重新定義類。

// 動態類加載器
public class DynamicClassLoader extends ClassLoader {
    public Class<?> findClass(byte[] b) throws ClassNotFoundException {
        return defineClass(null, b, 0, b.length);
    }
}

// 管理類:負責判斷修改並加載
public class ManageClassLoader {
    private DynamicClassLoader loader;
    private long lastModified = 0L;
    private Class<?> cachedClass;

    public Class<?> loadClass(String fileName) throws Exception {
        if (isModified(fileName)) {
            loader = new DynamicClassLoader();
            cachedClass = loader.findClass(readBytes(fileName));
        }
        return cachedClass;
    }

    private boolean isModified(String fileName) {
        File file = new File(fileName);
        if (file.lastModified() > lastModified) {
            lastModified = file.lastModified();
            return true;
        }
        return false;
    }

    private byte[] readBytes(String fileName) throws IOException {
        File file = new File(fileName);
        byte[] raw = new byte[(int) file.length()];
        try (FileInputStream fin = new FileInputStream(file)) {
            int r = fin.read(raw);
            if (r != raw.length) throw new IOException("讀取不完整");
        }
        return raw;
    }
}

適用場景:插件系統、規則引擎熱更新。
注意:需處理類卸載、父加載器委派等問題,生產環境建議成熟框架(如 Spring Loaded、JRebel)。

方案三:獨立線程 + sleep 輪詢

class FileMonitorThread extends Thread {
    private final String filePath;
    private long lastMod = 0L;

    public FileMonitorThread(String filePath) { this.filePath = filePath; }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            File file = new File(filePath);
            if (file.lastModified() > lastMod) {
                lastMod = file.lastModified();
                onFileChanged(); // 觸發回調
            }
            try {
                Thread.sleep(10000); // 10 秒間隔
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 保留中斷標誌
                break;
            }
        }
    }

    private void onFileChanged() {
        System.out.println("文件已更新:" + filePath);
        // 業務處理...
    }
}

優點:控制靈活,可隨時中斷;邏輯清晰。
缺點:輪詢間隔與實時性權衡。

方案對比與選型建議

方案實時性複雜度資源佔用推薦場景
Timer秒級低低簡單定時任務
自定義類加載器即時(文件變更觸發)高中類/配置熱加載
獨立線程睡眠間隔可控中低通用文件監聽、需優雅關閉

總結

根據業務對實時性、複雜度、維護性的要求選擇。大多數文件監測場景,獨立線程 + sleep 或成熟庫(如 Apache Commons IO FileAlterationMonitor)是穩健之選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved