2017-06-14 99 views
3

有没有办法在Java中安全且立即停止执行Thread?尤其是,如果方法的run()方法中的逻辑执行只有一次迭代,并且不定期检查任何标志,告诉它停止?Java - 如何从GUI中安全地停止Web应用程序中的线程?

我正在构建一个Web应用程序,使用它可以将整个文档的内容从一种语言翻译成另一种语言。

假设文档非常大,随后假定每个翻译都需要很长时间(比如20-25分钟),我的应用程序会为每个由用户发起的翻译创建一个单独的线程。用户可以看到活动翻译列表,并决定如果他/她希望停止特定的翻译工作。

这是我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. 
    } 

} 

我创建了一个TranslatorRunnable类,如下所示它实现了Runnable接口:

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."); 
    } 

} 

我创建的线程从翻译的文档外部类如下:

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

Now我的问题是,当用户点击GUI中的“停止”时,如何停止翻译过程(本质上是线程)?

我已阅读StackOverflow上以及在其他网站上的几个帖子,这告诉我有Runnable实现,这是我应该从run()方法内部定期检查,并决定何时停止内部volatile boolean标志。 See this post

这对我不起作用,因为run()方法只是调用Translator.translate()方法,而该方法本身需要很长时间。我在这里没有选择。

我读的下一件事是使用ExecutorService并使用其shutDownAll()方法。但即使在这里,我也必须在我的代码中定期处理InterruptedException。这一点再次超出了选项。涉及ExecutorService类的this documentation

我知道我不能使用Thread.stop(),因为它已被弃用,并可能导致所有线程通常使用的对象出现问题。

我有什么选择?

如果我的设计没有实质性改变,我的要求是否真的可行?如果是,请告诉我如何。

如果对我来说改变设计是绝对必要的,谁能告诉我什么是我能采取的最好的方法?

感谢, 斯利拉姆

+0

你可以使用t.interrupt() – Debu

回答

2

有没有一种方法能够安全,立即停止在Java线程的执行?

No.每个线程都是reponsible定期检查它是否已被中断,如果你想要一个更敏感的应用,以尽快

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

退出,你必须改变的逻辑(例如划分在小批量每个作业),因此每个线程检查的次数比每20-25分钟更频繁

0

如果您是创建Translator类的人,那么阻止您在定期检查的函数内添加某种类型的值,并且如果需要,可以停止读取行从文件这样的事情

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

这不是那么简单,因为translate()方法又调用了许多其他的类,方法和库,每个类可能加起来就是整个执行时间。因此,如果我希望我的应用程序在用户单击停止按钮时作出响应,我无法做到这一点。 – sriramsridharan

+0

是否有任何部分代码需要很长时间,并且您无法控制它或者是您控制的所有内容? – urag

+0

translate()方法反过来调用一个执行大部分任务的库,并且我无法控制它。除了调用这些库之外,我在translate()方法中所做的所有操作都是更新翻译状态(这是唯一可以控制的地方) – sriramsridharan