2016-07-29 7 views
1

Ich habe eine Anwendung, die Warnungen von anderen Anwendungen erhält, normalerweise einmal pro Minute oder so, aber ich muss in der Lage sein, höhere Volumen pro Minute zu behandeln. Die verwendete Schnittstelle und das Alert-Framework im Allgemeinen erfordern, dass Alerts asynchron verarbeitet und gestoppt werden können, wenn sie asynchron verarbeitet werden. Die Stop-Methode ist speziell als Stopp eines Threads dokumentiert. Ich habe den folgenden Code geschrieben, um einen AlertRunner-Thread zu erstellen und dann den Thread zu stoppen. Ist dies jedoch ein geeigneter Weg, um einen Thread zu beenden? Und wird dieser Code leicht skalierbar sein (nicht zu einem lächerlichen Volumen, aber vielleicht zu einer Warnung bei einer zweiten oder mehreren Warnungen gleichzeitig)?Ist dies eine sichere Möglichkeit, neue Threads zu generieren und sie zu beenden?

private AlertRunner alertRunner; 

@Override 
public void receive(Alert a) { 
    assert a != null; 
    alertRunner = new alertRunner(a.getName()); 
    a.start(); 
} 

@Override 
public void stop(boolean synchronous) { 
    if(!synchronous) { 
     if(alertRunner != null) { 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

class AlertRunner extends Thread { 
    private final String alertName; 

    public AlertRunner(String alertName) { 
     this.alertName = alertName; 
    } 

    @Override 
    public void run() { 
     try { 
      TimeUnit.SECONDS.sleep(5); 
      log.info("New alert received: " + alertName); 
     } catch (InterruptedException e) { 
      log.error("Thread interrupted: " + e.getMessage()); 
     } 
    } 
} 
+0

Ich frage mich, ob 'Thread.currentThread(). Interrupt();' tut, was Sie denken, dass es tut. Was es tut ist, es wird das _interrupted flag_ im Thread gesetzt, der deine 'stop()' Methode aufruft. Der Grund, warum ich misstrauisch bin, ist, dass es selten einen Grund gibt, dass ein Thread sich selbst unterbricht. –

Antwort

2

Dieser Code wird nicht leicht skalieren, weil Thread recht ist ‚schwer‘ Objekt. Es ist teuer zu erstellen und es ist teuer zu starten. Es ist viel besser, ExecutorService für Ihre Aufgabe zu verwenden. Es wird eine begrenzte Anzahl von Threads enthalten, die bereit sind, Ihre Anfragen zu verarbeiten:

int threadPoolSize = 5; 
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); 

public void receive(Alert a) { 
    assert a != null; 
    executor.submit(() -> { 
     // Do your work here 
    }); 
} 

Hier executor.submit() wird Ihre Anfrage in einem separaten Thread behandeln. Wenn jetzt alle Threads beschäftigt sind, wartet die Anfrage in einer Warteschlange, wodurch Ressourcen erschöpft werden. Es gibt auch eine Instanz von Future zurück, die Sie verwenden können, um auf den Abschluss der Behandlung zu warten, die Zeitüberschreitung einzustellen, das Ergebnis zu empfangen, die Ausführung abzubrechen und viele andere nützliche Dinge.

+0

Danke das ist genau das was ich gesucht habe! Wenn ich die Ausführung abbringe, wird nur die Ausführung der einen Warnung abgebrochen, die abgebrochen werden sollte? – SVN600

+0

Ja, der Aufruf von 'cancel()' auf einem 'Future' bricht die jeweilige Aufgabe ab:' Future f = executor.submit (() -> {...}); 'und dann' f.cancel (true) ' –

Verwandte Themen