2013-03-17 12 views
5

Ich bin ein Neuling für Nebenläufigkeit und Threads - und habe sie bei der Entwicklung meiner Anwendung bei der Arbeit verwendet. Im Wesentlichen habe ich eine Reihe von Threads in meiner RMI-Anwendung (serverseitige Komponente), die Änderungen in Dateien abfragen (diese Dateien werden alle paar Sekunden aktualisiert).Daemon-Thread Java

Beim Testen auf einer Dev-Box habe ich den Server von der Kommandozeile aus ausgeführt und dann manuell geschlossen, wenn ich fertig bin, spüle und wiederhole den ganzen Tag.

Wie es sich herausstellt - ich denke, dass meine Threads möglicherweise nicht aufhören, wenn ich die Befehlszeile schließe und weiterhin mit der Verarbeitung fortfahren. Dies führt zu einigen sehr schlechten Nebenwirkungen - obwohl ich mir nicht 100% sicher bin, ob dies möglich ist, hoffentlich kann jemand bestätigen, dass dies der Fall sein könnte.

Wenn ich einen Thread zu einem Daemon mache - heißt das, wenn ich die Befehlszeile schließe - werden diese Threads automatisch gestoppt? Ich brauche eine Möglichkeit, die Anwendung schön das Beendens aber, da der Server wird schließlich von AutoSys ausgeführt wird Ich bin nicht sicher, was der beste Weg, alle Themen zu machen beenden, wenn heruntergefahren

Dank

+0

diese Frage hat eine etwas andere Neigung und hat auch eine andere Frage innerhalb des Körpers - ich würde es wirklich schätzen, wenn es nicht geschlossen wurde – Biscuit128

+0

Ihre Hauptfrage ergibt sich aus einem Mangel an Verständnis dessen, was "Daemon" für Java bedeutet der Link zu der doppelten Frage. Was Ihre andere Frage anbelangt (ich nehme an, es handelt sich um die Frage, wie Sie Ihre Anwendung sicher beenden können), sollte sie separat gestellt werden, da es sich um eine separate Frage handelt. – Jeffrey

Antwort

1

Der folgende Code zeigt eine Erstellung Thread-Pool mit einem Dummy-Lauf-Task, dieser Task wird dann gestartet und wenn die Anwendung beendet wird, wird ein Shutdown-Hook ausgeführt, der alle laufenden Tasks abbricht und den Thread-Pool sauber schließt.

Sie müssen Callable nicht verwenden, wie ich habe, können Sie Runnables und die Methode threadPool.execute verwenden und einfach den threadPool beenden, der ein wenig weniger elegant ist.

final ExecutorService threadPool = Executors.newCachedThreadPool(); 
    final List<Future<Void>> runningTasks = new ArrayList<>(); 
    Future<Void> task = threadPool.submit(new Callable<Void>() { 

     @Override 
     public Void call() throws Exception { 
      int count = 0; 
      while(true) { 
       System.out.println(++count); 
       Thread.sleep(1000); 
      } 
     } 
    }); 
    runningTasks.add(task); 

    Runtime.getRuntime().addShutdownHook(new Thread() { 
     @Override 
     public void run() { 
      for(Future<Void> runningTask : runningTasks) { 
       runningTask.cancel(true); 
      } 
      threadPool.shutdownNow(); 
     } 
    }); 

Shutdown-Hooks sind für eigenständige Anwendungen. In einem Java EE-Container können Sie dasselbe mit einem javax.servlet.ServletContextListener tun.

+0

danke für den Rat, bedeutet dies, dass ich den Servlet Context Listener im Gegensatz zu dem Shutdown-Haken verwenden muss? ist das ähnlich? – Biscuit128

+0

In einer eigenständigen Java-Anwendung können Sie einen Shutdown-Hook verwenden, in einer Java-Webanwendung verwenden Sie den ContextListener. Hängt davon ab, ob Sie Threads auf dem Client oder Server bereinigen. – JayTee

+0

ja alle Threads müssen gestoppt werden. – Biscuit128

1

Threads, die in einer Java Virtual Machine ausgeführt werden. Wenn Sie die JVM stoppen, werden die Threads nicht mehr ausgeführt. Sie könnten sehen, wie Sie die JVM verlassen, indem Sie den Stecker von Ihrem Computer ziehen: nichts kann mehr laufen.

0

Die RMI Runtime erstellt Threads, die Sie nicht stoppen können. Die einzige Möglichkeit, den Dienst herunterzufahren, ist eine System.exit().

Ich mache das in einem separaten Thread. Nachher: ​​new ShutThread(). Start() wartet der heruntergefahrene Thread 2 Sekunden, um allen vergehenden Nachrichten eine Chance zu geben, die Reise abzuschließen, und gibt dann die System.exit() aus.

+0

also für einen Server, der von der Kommandozeile aus gestartet wird - ohne Argumente mit java -jar server.jar - sobald dies ausgeführt wird, wie übergeben wir dann eine Nachricht an sie, die sie elegant beenden soll? – Biscuit128

+0

Guter Punkt. Ich schreibe Server-Software so einschließlich einer Methode zum Herunterfahren ist Standard-Praxis. Wenn andere diese Funktion nicht zulassen, sollten sie das vielleicht tun. – edharned