2016-07-28 6 views
0

Meine Anforderung ist, MongoDB alle 30s für jede Datenänderung in einer Sammlung abzufragen. Ich habe Java CompletableFuture.runAsync verwendet, um diese Funktion als unten erfassten Code zu implementieren. Ich habe das Programm für einen Tag getestet und es scheint gut zu funktionieren.Java CompletableFuture.runAsync Rekursion ... ein potenzielles Risiko?

Meine Fragen sind:

  1. Würde ein mögliches Risiko von OOM „Stack-Überlauf“ Ausnahme da sein, wenn ich für lange Zeit läuft halten?
  2. Meine Threadpoolgröße ist 3, aus der Protokolldatei habe ich festgestellt, dass die ersten 2 Läufe pool-1-thread-1 und pool-1-thread-2 verwenden, ab dem dritten und so weiter pool-1-thread-3 für einige Zeit, dann benutze pool-1-thread-1/pool-1-thread-2 für einen bestimmten Zeitraum ... wäre da ein potenzielles Problem oder ist es normal?

    private static ExecutorService executor = Executors.newFixedThreadPool(3); 
    
    private void watch(){ 
        CompletableFuture<Void> watchForLeadershipChange = 
         CompletableFuture.runAsync(() -> pollForChanges(), executor); 
    } 
    
    private void pollForChanges() { 
        //Query MongoDB collection and do some logic 
    
        TimeUnit.SECONDS.sleep(30); 
        watch(); 
    } 
    
+1

Warum nicht 'ScheduledExecutorService'? Oder nur eine 'while()' Schleife? –

+0

Die Aufgaben, die von verschiedenen Poolthreads übernommen werden: Ja, das ist normal. – Fildor

Antwort

1
  1. Würde ein mögliches Risiko von OOM "Stack-Überlauf" Ausnahme da sein, wenn ich für lange Zeit laufen halten? Nein. Während pollForChanges() Aufrufe watch(), die nachfolgenden Aufrufe von pollForChanges() geschehen asynchron in (wahrscheinlich) einem anderen Thread. In jedem Fall wird es immer einen neuen Stapelzeiger haben.
  2. Meine Thread Größe 3, aus der Protokolldatei fand ich, dass die ersten zwei Läufe ... Welcher Faden die ExecutorService wählt ist eine Implementierung Detail dieser ExecutorService. Das Verhalten, das Sie beobachten, ist nicht ungewöhnlich oder unerwartet.

All das wird gesagt - dies mit einem ScheduledExecutorService etwas ganz trivial zu tun, ein sehr Umwege ist wie in den Kommentaren darauf hingewiesen wurde:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 

scheduler.scheduleWithFixedDelay(
     () -> queryMongoAndDoSomeLogic(), 
     0, 
     30, 
     TimeUnit.SECONDS);