繁体   English   中英

Java - 如何从GUI安全地停止Web应用程序中的线程?

[英]Java - How do I safely stop a thread in a Web App from the GUI?

有没有办法安全地立即停止在Java中执行Thread? 特别是,如果Runnable实现的run()方法内的逻辑执行一次迭代 ,并且不定期检查任何告诉它停止的标志?

我正在构建一个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();

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

我已经在StackOverflow以及其他网站上阅读了一些帖子,这些帖子告诉我在Runnable实现中有一个volatile boolean标志,我应该定期从run()方法内部检查并确定何时停止。 看这篇文章

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

我读到的下一件事是使用ExecutorService并使用其shutDownAll()方法。 但即使在这里,我也必须在我的代码中定期处理InterruptedException 这个,再次出于选择。 提到了ExecutorService类的这个文档

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

我有什么选择?

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

如果我绝对有必要改变设计,有人能告诉我什么是最好的方法吗?

谢谢,Sriram

有没有办法安全地立即停止在Java中执行Thread?

不可以。每个线程都有责任定期检查是否已经中断以便尽快退出

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

如果你想要一个响应更快的应用程序,你必须改变逻辑(例如以较小的批次划分每个作业),所以每个线程比每20-25分钟更频繁地进行一次检查

如果您是创建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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM