2017-06-14 2 views
3

Gibt es eine Möglichkeit, die Ausführung eines Threads in Java sicher und sofort zu stoppen? Insbesondere wenn die Logik innerhalb der run() Methode der Runnable Implementierung führt nur eine einzige Iteration und nicht regelmäßig überprüft für jede Flagge, die es zu stoppen erzählt?Java - Wie kann ich einen Thread in einer Web App über die GUI sicher stoppen?

Ich bin den Aufbau einer Web-Anwendung, mit denen ein Benutzer den Inhalt eines gesamten Dokuments von einer Sprache in eine andere übersetzen kann.

Angenommen, die Dokumente sind extragroß und die Annahme, dass jede Übersetzung sehr lange dauern wird (etwa 20-25 Minuten), erstellt meine Anwendung einen separaten Thread für jede Übersetzung, die von den Benutzern initiiert wird. Ein Benutzer kann eine Liste aktiver Übersetzungen sehen und entscheiden, einen bestimmten Übersetzungsauftrag zu stoppen, wenn er dies wünscht.

Das ist mein Translator.java

public class Translator { 
    public void translate(File file, String sourceLanguage, String targetLanguage) { 
    //Translation happens here 
    //....... 
    //Translation ends and a new File is created. 
    } 

} 

ich eine TranslatorRunnable Klasse erstellt haben, die die Runnable-Schnittstelle implementiert, wie folgt:

public class TranslatorRunnable implements Runnable { 

    private File document; 
    private String sourceLanguage; 
    private String targetLanguage; 

    public TranslatorRunnable(File document, String sourceLanguage, String targetLanguage) { 
     this.document = document; 
     this.sourceLanguage = sourceLanguage; 
     this.targetLanguage = targetLanguage; 
    } 

    public void run() { 
     // TODO Auto-generated method stub 
     Translator translator = new Translator(); 
     translator.translate(this.document, this.sourceLanguage, this.targetLanguage); 
     System.out.println("Translator thread is finished."); 
    } 

} 

Ich bin für die Übersetzung eines Dokuments aus einer den Faden zu schaffen äußere Klasse wie folgt:

TranslatorRunnable tRunnable = new TranslatorRunnable(document, "ENGLISH", "FRENCH"); 
Thread t = new Thread(tRunnable); 
t.start(); 

Jetzt Mein Problem ist, wie stoppe ich einen Übersetzungsprozess (im Wesentlichen ein Thread), wenn der Benutzer auf "Stop" in der GUI klickt?

Ich habe ein paar Beiträge auf Stackoverflow sowie auf anderen Seiten, die mir eine volatile boolean Flagge innerhalb der Runnable Implementierung haben, sagen zu lesen, die ich aus dem Innern des run() Verfahren regelmäßig überprüfen sollte und entscheiden, wann zu stoppen. See this post

Dies funktioniert nicht für mich, da die Methode run() nur die Translator.translate() -Methode aufruft, die selbst lange dauern wird. Ich habe hier keine Wahl.

Das nächste, was ich lese, ist ExecutorService zu verwenden und seine shutDownAll() Methode zu verwenden. Aber selbst hier würde ich regelmäßig in meinem Code mit InterruptedException umgehen müssen. Dies ist wieder aus der Option. Erworben this documentation der ExecutorService-Klasse.

Ich weiß, dass ich Thread.stop() nicht verwenden kann, da es veraltet ist und Probleme mit Objekten verursachen kann, die häufig von allen Threads verwandt werden.

Welche Optionen habe ich?

Ist meine Anforderung ohne wesentliche Änderungen an meinem Design wirklich machbar? Wenn ja, bitte sag mir wie.

Wenn es unbedingt notwendig ist für mich das Design zu ändern, könnte mir jemand sagen, was der beste Ansatz ist, kann ich nehmen?

Danke, Sriram

+0

können Sie t.interrupt() verwenden – Debu

Antwort

2

Gibt es einen Weg, um die Ausführung eines Threads in Java, um sicher und sofort zu stoppen?

No.jeder Thread ist reponsible in regelmäßigen Abständen zu überprüfen, ob es so schnell wie möglich

if (Thread.currentThread().isInterrupted()) { 
    // release resources. finish quickly what it was doing 
} 

, wenn Sie eine reaktions Anwendung verlassen wollen unterbrochen wurde, müssen Sie die Logik ändern (zB jeden Auftrag in kleineren Chargen aufteilen) so jeder Thread überprüft diese Prüfung häufiger als alle 20-25 Minuten

0

Wenn Sie derjenige sind, der die Translator-Klasse erstellt hat, werden Sie keine Werte in der Funktion hinzufügen, die regelmäßig überprüft wird, und wenn nötig, die Zeilen nicht mehr lesen von der Datei so etwas

public static List<String> readFile(String filename) 
{ 
    List<String> records = new ArrayList<>(); 
    try 
    { 
     BufferedReader reader = new BufferedReader(new FileReader(filename)); 
     String line; 
     while ((line = reader.readLine()) != null) 
     { 
      String[] split = line.split("\\s+"); 
      records.addAll(Arrays.asList(split)); 
      if (needsToStop) { 
       break; //Or throw exception 
      } 
     } 
     reader.close(); 
     return records; 
    } 
    catch (Exception e) 
    { 
     System.err.format("Exception occurred trying to read '%s'.", filename); 
     e.printStackTrace(); 
     return null; 
    } 
} 
+0

Es ist nicht so einfach, da die translate() -Methode wiederum viele andere Klassen, Methoden und Bibliotheken aufruft, von denen jede zur Gesamtzeit der Ausführung addiert werden kann. Daher kann ich das nicht tun, wenn ich möchte, dass meine Anwendung reagiert, wenn der Benutzer auf die Stopp-Schaltfläche klickt. – sriramsridharan

+0

Gibt es einen Teil des Codes, der lange braucht und Sie keine Kontrolle darüber haben oder alles unter Ihrer Kontrolle steht? – urag

+0

Die translate() -Methode wiederum ruft eine Bibliothek auf, die den Großteil der Aufgabe erledigt, und ich habe keine Kontrolle darüber. Alles, was ich innerhalb der translate() -Methode tun, abgesehen von dem Aufruf dieser Bibliotheken ist, den Status der Übersetzung zu aktualisieren (dies ist der einzige Ort, an dem ich die Kontrolle habe) – sriramsridharan

Verwandte Themen