buduję na Alexeis odpowiedź, ale nie sądzę, że było wystarczająco jasne ... spojrzeć na ten kod Przykład:
WatchService service = dir.getFileSystem().newWatchService();
WatchKey key = dir.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
System.out.println(key);
for(;;) {
WatchKey k = service.take();
System.out.println(k);
for(WatchEvent<?> ev:k.pollEvents()) {
System.out.println(ev.kind());
if(ev.kind() == OVERFLOW) continue;
//TODO
System.out.println(ev.context());
}
if(!k.reset()) break;
}
key.cancel();
Jeśli sprawdzić println(key)
/println(k)
wyjścia, zobaczysz, że ten sam obiekt jest wielokrotnie zwracany; take()
zwraca za każdym razem, gdy klucz jest sygnalizowany, więc aby użyć wielu kluczy z tym samym WatchService
, po prostu sprawdź, który klucz został zwrócony za każdym razem. Oznacza to również, że twoja pętla blokuje tak długo, jak długo klucz nie był sygnalizowany - dokładnie to, co chcesz.
the if(!k.reset()) break;
również ma kluczowe znaczenie; o tym zapomniałem, pisząc swój komentarz na temat odpowiedzi Alexeisa. Moje założenie było takie, że take()
jest wywoływane przez register()
, a zatem żaden klucz nie powinien zostać zwrócony w moim kodzie użytkownika, ponieważ register() już go wykorzystał. Z tego błędnego założenia nie wiedziałem, co się właściwie dzieje.
Nie rozumiem tutaj problemu. Nawet w przypadku modelu oddzwaniania musisz uzyskać zdarzenia od _somhere_. Zasadniczo jest to inny wątek, który wykonuje wywołanie zwrotne. Możesz uważać usługę "WatchService" za "wywołującego wywołanie zwrotne" ... – fge
fge: Jeśli zajrzysz do hierarchii klas WatchService, zobaczysz, że tylko ogólna usługa PollingWatchService używa naiwnego, zajętego mechanizmu pod maską. Inne usługi zegarków opierają się na funkcjach systemu operacyjnego, które przechwytują zdarzenia bardziej efektywnie - prawdopodobnie tak wydajnie, jak oczekiwanie na przesłanie bajtów do strumienia. Sposób, w jaki projektuje się API usługi Watch, powoduje, że ta korzyść jest ponownie odbierana, gdy aplikacja próbuje odbierać zdarzenia z WatchKey, ponieważ nie ma blokującej metody waitForEvent() lub podobnej. Istnieje olbrzymia różnica między wątkiem bezczynności i zajętości tła. –
"EDYCJA": Zobacz moją odpowiedź na niestosowne podejście, które działa. Mimo to sposób wyjaśniony w Poradniku Java http://docs.oracle.com/javase/tutorial/essential/io/notification.html jest zajęty ... –