繁体   English   中英

在应用程序退出时停止监视程序服务

[英]stop watcher service on application quit

我使用gradleapplication插件来运行gradle目录中更改的应用程序。

我的主班看起来像这样

public static void main(String[] args) throws IOException {
    WatcherThread thread = new WatcherThread(EXTENSION_FOLDER);
    thread.start();

    try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
        String input = null;
        ConsoleInputController controller = new ConsoleInputController(br);
        while (!QUIT_COMMAND.equals(StringUtils.trim(input))) {
            System.out.println(CONSOLE_TEMPLATE);
            System.out.println("input (to exit write [quit]):> ");

            input = br.readLine();
            controller.handleInput(input);
        }
    } catch (IOException exc) {
        LOGGER.error("Failed to process input.", exc);
    }

    thread.stopThread();
}

WatcherThread是使用WatcherService的线程类(Java WatchService的某些包装器)

public class WatcherThread extends Thread {
    private static final Logger LOGGER = LoggerFactory.getLogger(WatcherThread.class);

    private boolean watch = true;
    private WatcherService watcherService;

    public WatcherThread(String searchingPath) throws IOException {
        watcherService = new WatcherService(Paths.get(searchingPath));
    }

    @Override
    public void run() {
        LOGGER.info("Artifact watching thread started.");
        while(watch) {
            if (!watcherService.watch()) {
                break;
            }
        }
        LOGGER.info("Artifact watching thread stopped.");
    }

    public void stopThread() {
        watch = false;
    }
}

WatcherService看起来像这样

public class WatcherService {
    private static final Logger LOGGER = LoggerFactory.getLogger(WatcherThread.class);

    private final WatchService watcher;
    private final Map<WatchKey, Path> keys;
    private boolean trace;

    WatcherService(Path dir) throws IOException {
        watcher = FileSystems.getDefault().newWatchService();
        keys = new HashMap<>();

        register(dir);

        trace = true;
    }

    private void register(Path dir) throws IOException {
        WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
        if (trace) {
            Path prev = keys.get(key);
            if (null == prev) {
                LOGGER.info("Register path: [{}].", dir);
            } else {
                if (!dir.equals(prev)) {
                    LOGGER.info("Updated path: [{}] -> [{}].", prev, dir);
                }
            }
        }
        keys.put(key, dir);
    }

    boolean watch() {
        WatchKey key;
        try {
            key = watcher.take();
        } catch (InterruptedException exc) {
            return false;
        }

        Path dir = keys.get(key);
        if (null == dir) {
            LOGGER.warn("WatchKey is not recognized!");
            return false;
        }

        // forEach?
        for (WatchEvent event: key.pollEvents()) {
            LOGGER.info("Polling events");
            WatchEvent.Kind kind = event.kind();
            if (OVERFLOW == kind) {
                continue;
            }

            WatchEvent<Path> ev = (WatchEvent<Path>) event;
            Path name = ev.context();
            Path child = dir.resolve(name);

            LOGGER.info("Event occurred [{}] in [{}].", event.kind().name(), child);
            WatchEventResolver.resolveEvent(ev, child);
        }

        boolean valid = key.reset();
        if (!valid) {
            keys.remove(key);

            if (keys.isEmpty()) {
                return false;
            }
        }

        return true;
    }
}

当我不start WatcherThread ,控制台输入可以正常工作。 我可以毫无问题地quit 但是,当我运行线程并想要退出时,它正在等待几秒钟,然后才结束。

据我了解, WatchService不能停止监视目录。

如何立即停止quit应用程序?

看来您在WatcherService类中需要一个额外的方法,该方法调用watcher.close() 然后,在WatcherThread类中,可以在stopThread()内部调用该方法。

WatchServiceJavadoc中 ,您可以看到take()一直在等待。 您可以通过关闭它来强制完成它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM