You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中实现每秒调用数据库获取状态,完成XML导入SQL基准测试?

实现文件删除事件触发后每秒查询数据库导入状态

要在文件删除事件触发后每秒调用数据库获取导入状态,核心是避免阻塞文件夹监控的主线程,同时实现定时查询逻辑。以下是两种可行的实现方案:

方案1:使用ScheduledExecutorService(推荐)

这种方式通过线程池管理定时任务,更规范且易于控制任务生命周期,适合生产环境。

修改后的完整代码:

import java.io.IOException;
import java.nio.file.*;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.*;

public class Application extends SqlUtils {

    private static String folderPath = "D:\\EntityImportEversana";
    // 单线程调度池,管理定时查询任务
    private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public static void main(final String[] args) throws IOException, InterruptedException {

        System.out.println("Running file verifier");
        System.out.println("monitoring folder " + folderPath);
        SqlUtils sql = new SqlUtils();

        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path path = Paths.get(folderPath);
        path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
        
        WatchKey key;
        while ((key = watchService.take()) != null) {
            for (WatchEvent<?> event : key.pollEvents()) {
                System.out.println("Event kind:" + event.kind() + ". File affected: " + event.context() + ".");
                
                if (event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)) {
                    // 定义查询任务,支持自我取消
                    Runnable queryTask = new Runnable() {
                        private Future<?> selfFuture;

                        public void setSelfFuture(Future<?> future) {
                            this.selfFuture = future;
                        }

                        @Override
                        public void run() {
                            Instant start = Instant.now();
                            HashMap<String, List> statusMap = sql.checkFileImport();
                            Instant end = Instant.now();
                            System.out.println("查询耗时: " + Duration.between(start, end));

                            // 根据业务逻辑判断导入是否完成,完成则取消任务
                            if (checkIfImportCompleted(statusMap)) {
                                System.out.println("导入已完成,停止定时查询");
                                if (selfFuture != null) {
                                    selfFuture.cancel(false);
                                }
                            }
                        }
                    };

                    // 提交定时任务:延迟0秒启动,每秒执行一次
                    ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(queryTask, 0, 1, TimeUnit.SECONDS);
                    queryTask.setSelfFuture(future);
                }
            }
            key.reset();
        }

        watchService.close();
        scheduler.shutdown(); // 程序退出时关闭线程池,避免资源泄漏
    }

    // 自定义方法:根据数据库返回的状态判断导入是否完成
    private static boolean checkIfImportCompleted(HashMap<String, List> statusMap) {
        // 示例逻辑:请根据你的业务需求修改
        return statusMap != null 
                && statusMap.containsKey("import_status") 
                && statusMap.get("import_status").contains("SUCCESS");
    }
}

关键说明:

  • ScheduledExecutorService负责管理定时任务,不会阻塞WatchService的主线程,确保文件夹监控正常响应其他事件。
  • 每个删除事件对应一个独立的定时任务,任务内部判断导入状态,完成后自动取消。
  • 必须实现checkIfImportCompleted方法,贴合你的实际业务逻辑(比如检查导入状态字段、记录数等)。

方案2:使用普通线程(快速实现)

如果是简单场景,也可以直接启动新线程,通过Thread.sleep()实现每秒查询:

修改事件处理部分的代码:

if (event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)) {
    new Thread(() -> {
        while (true) {
            Instant start = Instant.now();
            HashMap<String, List> statusMap = sql.checkFileImport();
            Instant end = Instant.now();
            System.out.println("查询耗时: " + Duration.between(start, end));

            // 判断导入完成则退出循环
            if (checkIfImportCompleted(statusMap)) {
                System.out.println("导入已完成,停止查询");
                break;
            }

            try {
                Thread.sleep(1000); // 每秒执行一次
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
    }).start();
}

注意事项:

  • 确保SqlUtils.checkFileImport()是线程安全的,避免多线程调用时出现并发问题。
  • 程序退出时要注意清理线程,避免资源泄漏。

内容的提问来源于stack exchange,提问作者Peter Penzov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:01:08