2017-07-13 1 views
1

Ich versuche, eine Methode mehrmals alle 60 Sekunden aufzurufen, bis eine Erfolg-Antwort von der Methode tatsächlich einen Rest Endpunkt auf einem anderen Dienst aufruft. Ab jetzt verwende ich tun while-Schleife undJava Mit CountDownLatch eine Methode bis eine Erfolgsantwort abfragen

Thread.sleep(60000); 

mit der Haupt-Thread warten Sie 60 Sekunden zu machen, die ich fühle mich aufgrund Concurrency Probleme nicht der ideale Weg ist.

stieß ich auf die CountDownLatch Methode

CountDownLatch latch = new CountDownLatch(1); 
boolean processingCompleteWithin60Second = latch.await(60, TimeUnit.SECONDS); 

@Override 
public void run(){ 

    String processStat = null; 
    try { 
     status = getStat(processStatId); 
     if("SUCCEEDED".equals(processStat)) 
     { 
      latch.countDown(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

ich die run-Methode in einer anderen Klasse haben, die runnable implementiert. Nicht in der Lage, dies zum Funktionieren zu bringen. Irgendeine Idee was falsch ist?

+0

Warum rufst du zweimal an? Was meinst du damit, dass das nicht funktioniert? – bmargulies

+0

Sorry für den Fehler. Ich habe es korrigiert. Das Problem hier ist, dass ich die Methode von der Runnable-Klasse aufrufen und nicht in der Lage bin herauszufinden, wie die Erfolgs-/Fehlerantwort von der Runnable-Klasse an den Hauptthread übergeben wird. – Upen

Antwort

0

Schließlich wurde es mit Executor-Framework zu arbeiten.

  final int[] value = new int[1]; 
      pollExecutor.scheduleWithFixedDelay(new Runnable() { 

       Map<String, String> statMap = null; 

       @Override 
       public void run() { 

        try { 
         statMap = coldService.doPoll(id); 
        } catch (Exception e) { 

        } 
        if (statMap != null) { 
         for (Map.Entry<String, String> entry : statMap 
           .entrySet()) { 
          if ("failed".equals(entry.getValue())) { 
           value[0] = 2; 

           pollExecutor.shutdown(); 
          } 
         } 
        } 
       } 

      }, 0, 5, TimeUnit.MINUTES); 
      try { 
       pollExecutor.awaitTermination(40, TimeUnit.MINUTES); 
      } catch (InterruptedException e) { 

      } 
2

Sie könnten einen CompletableFuture statt CountDownLatch verwenden das Ergebnis zurück:

CompletableFuture<String> future = new CompletableFuture<>(); 

invokeYourLogicInAnotherThread(future); 

String result = future.get(); // this blocks 

Und in einem anderen Thread (möglicherweise in einer Schleife):

@Override 
public void run() { 

    String processStat = null; 
    try { 
     status = getStat(processStatId); 
     if("SUCCEEDED".equals(processStat)) 
     { 
      future.complete(processStat); 
     } 
    } catch (Exception e) { 
     future.completeExceptionally(e); 
    } 
} 

future.get() blockiert, bis etwas über vorgelegt complete() Methode und geben Sie den übergebenen Wert zurück, oder es wird die Ausnahme ausgelöst, die über completeExceptionally() in einem ExecutionException verpackt wurde.

Es gibt auch get() Version mit Zeitlimit:

String result = future.get(60, TimeUnit.SECONDS); 
+0

Das Projekt wird auf Java 7 ausgeführt. Sie können CompleteFuture nicht verwenden. – Upen

+0

Verwendet Guava eine Option? Ich meine seine ListenableFuture: https://google.github.io/guava/releases/21.0/api/docs/com/google/common/util/concurrent/ListenableFuture.html –

Verwandte Themen