Java WatchService中的高负载

时间:2016-11-28 14:41:32

标签: java bash watchservice

我注册了一个Java WatchService来检查文件是否被修改。如果您使用Sublime或Notepad等文件查看器,一切正常。但是,如果我尝试在服务器上使用bash文件查看器(如vim)编辑我的文件(在本例中是一个config.properties文件),则会永久执行while循环,从而在系统上施加高负载并输出以下内容:

2016-11-28 15:17:38.031 [INFO ] [Thread-7] PropertyReader pollPropertyFileModification - while (true)
2016-11-28 15:17:38.031 [INFO ] [Thread-7] PropertyReader pollPropertyFileModification - while (true)
2016-11-28 15:17:38.031 [INFO ] [Thread-7] PropertyReader pollPropertyFileModification - while (true)

这是一个错误还是我错误地使用了WatchService?这是我的代码:

    private void pollPropertyFileModification() {
        logger.debug("entry");

        final Path path = Paths.get(System.getProperty(Constants.CONFIG_FILE));
        logger.debug("Filename: {}", path.getFileName());
        logger.debug("Parent Path: {}", path.getParent());

        try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
            path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
            final WatchKey watchKey = watchService.take();
//            final WatchKey watchKey = watchService.poll(10, TimeUnit.SECONDS);

            while (true) {
                logger.info("while (true)");
                for (WatchEvent<?> event : watchKey.pollEvents()) {
                    // we only register "ENTRY_MODIFY" so the context is always a Path.
                    final Path filename = (Path) event.context();
                    logger.info("Filename: {}", filename);

                    if (filename.endsWith(path.getFileName())) {
                        logger.info("{} has changed", filename);
                    }
                }

                // reset the key
                if (!watchKey.reset()) {
                    logger.info("Key has been unregistered");
                    break;
                }
            }
        } catch (IOException ex) {
            logger.error("IOException", ex);

        } catch (InterruptedException ex) {
            logger.error("InterruptedException", ex);
        }

        logger.debug("exit");
    }

更新
正如@Ironcache指出的那样,watchService.take();调用位置错误,必须放在循环中

    private void pollPropertyFileModification() {
        logger.debug("entry");

        final Path path = Paths.get(System.getProperty(Constants.CONFIG_FILE));
        logger.debug("Filename: {}", path.getFileName());
        logger.debug("Parent Path: {}", path.getParent());

        try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
            path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);

            while (true) {
                logger.info("while (true)");

                final WatchKey watchKey = watchService.take();

                for (WatchEvent<?> event : watchKey.pollEvents()) {
                    // we only register "ENTRY_MODIFY" so the context is always a Path.
                    final Path filename = (Path) event.context();
                    logger.info("Filename: {}", filename);

                    if (filename.endsWith(path.getFileName())) {
                        logger.info("{} has changed", filename);
                    }
                }

                // reset the key
                if (!watchKey.reset()) {
                    logger.info("Key has been unregistered");
                    break;
                }
            }
        } catch (IOException ex) {
            logger.error("IOException", ex);

        } catch (InterruptedException ex) {
            logger.error("InterruptedException", ex);
        }

        logger.debug("exit");
    }

0 个答案:

没有答案