2013-09-03 22 views
7

W documentation for the overflow stany:W interfejsie API usługi jdk7 watch, kiedy nastąpi wywołanie zdarzenia OVERFLOW?

przelewowy - Wskazuje, że wydarzenia mogły zostać utracone lub wyrzucić.

Nie twierdzi, w jakiej sytuacji należy spodziewać się utraty lub odrzucenia wydarzenia? Początkowo myślałem, że będzie to wynik szybkiego zapisania wielu plików w folderze. Stworzyłem kilka tysięcy plików o zerowym rozmiarze i przeniosłem je do monitorowanego katalogu. Bez przepełnienia.

Czego mi brakuje?

+0

"Systemy plików mogą zgłaszać zdarzenia szybciej, niż można je odzyskać lub przetworzyć, a implementacja może narzucić nieokreślony limit liczby zdarzeń, które może zgromadzić. W przypadku, gdy implementacja świadomie odrzuca zdarzenia, wówczas organizuje metodę pollEvents klucza, aby zwrócić element z typem zdarzenia OVERFLOW. To zdarzenie może być używane przez konsumenta jako wyzwalacz do ponownego zbadania stanu obiektu. "Od [JavaDoc] (http://docs.oracle.com/javase/7/docs/api/java/nio/file /WatchService.html) Być może nie załadowałeś wystarczająco dużo, aby utworzyć przepełnienie – Fildor

+0

@Fildor, dzięki. Zapomniałem przeczytać tę JavaDoc. Proszę napisać jako odpowiedź, abym mógł ją zaakceptować – Vitaliy

Odpowiedz

6

„Systemy plików mogą zgłaszać zdarzenia szybciej niż mogą być pobierane lub przetwarzane i implementacja może nałożyć nieokreśloną limit liczby wydarzeń, które może narastać. W przypadku, gdy realizacja świadomie odrzuca wydarzenia następnie układa dla klucza pollEvents metoda zwracania elementu z typem zdarzenia OVERFLOW. To zdarzenie może być używane przez konsumenta jako wyzwalacz do ponownego zbadania stanu obiektu . "

Od JavaDoc.

Zobacz także odpowiedź Steven C. Jego punkt widzenia na temat nieprzewidzianych zdarzeń robi różnicę, jak sądzę.

6

Utworzyłem kilka tysięcy plików o zerowym rozmiarze i przeniosłem je do monitorowanego katalogu. Bez przepełnienia.

Przypuszczalnie konsumujesz zdarzenia równolegle z ich tworzeniem. Jeśli chcesz wyzwolić przepełnienie, spróbuj wstrzymać konsumpcję zdarzeń, wygenerować ich dużo (jak wyżej), a następnie wznowić konsumpcję. Limit liczby nieoczekiwanych zdarzeń może być ograniczony, ponieważ system operacyjny może buforować.

+0

Rzeczywiście zadziałało! – Vitaliy

2

Minimal przykład, który generuje przelewa

Wystarczy utworzyć pliki po watcherService.register i przed watcherService.take.

Invoke z:

java Overflow 256 

kontrolować liczbę zdarzeń.

Java 7 i Ubuntu 14.04 maxes na 512 wydarzeniach.

Za każdym razem, gdy wystąpiło przepełnienie, tylko jedno zdarzenie zostało zwrócone przez pollEvents(), ale nie jest to bardzo jasno określone w Javadoc.

Uważam to za dziwne, że granica ta jest tak mała, biorąc pod uwagę, że:

Kod:

import java.io.File; 
import java.io.IOException; 
import java.nio.file.FileSystems; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.nio.file.StandardWatchEventKinds; 
import java.nio.file.WatchEvent; 
import java.nio.file.WatchService; 
import java.util.List; 

public class Overflow { 

    @SuppressWarnings("unchecked") 
    static <T> WatchEvent<T> cast(WatchEvent<?> event) { 
     return (WatchEvent<T>)event; 
    } 

    public static void main(final String[] args) throws InterruptedException, IOException { 
     int nfiles; 
     if (args.length > 0) 
      nfiles = Integer.parseInt(args[0]); 
     else 
      nfiles = 10_000; 
     Path directory = Files.createTempDirectory("watch-service-overflow"); 
     final WatchService watchService = FileSystems.getDefault().newWatchService(); 
     directory.register(
       watchService, 
       StandardWatchEventKinds.ENTRY_CREATE, 
       StandardWatchEventKinds.ENTRY_DELETE); 
     final Path p = directory.resolve(Paths.get("Hello World!")); 
     for (int i = 0; i < nfiles; i++) { 
      Files.createFile(p); 
      Files.delete(p); 
     } 
     List<WatchEvent<?>> events = watchService.take().pollEvents(); 
     for (final WatchEvent<?> event : events) { 
      if (event.kind() == StandardWatchEventKinds.OVERFLOW) { 
       System.out.println("Overflow."); 
       System.out.println("Number of events: " + events.size()); 
       return; 
      } 
     } 
     System.out.println("No overflow."); 
     Files.delete(directory); 
    } 
}