0
我使用gradle
和application
插件來運行監視目錄中更改的應用程序。應用程序退出時停止監視器服務
我的主類看起來像這樣
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
申請?
如果我在'stopThread'中調用'close',它會拋出'ClosedWatchServiceException'。 – lapots
的確如此,您可以在代碼中處理與InterruptedException相同的問題。 –
哦,我明白了!謝謝! – lapots