Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-如何从GUI安全地停止Web应用程序中的线程?_Java_Multithreading_Concurrency - Fatal编程技术网

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

Java-如何从GUI安全地停止Web应用程序中的线程?,java,multithreading,concurrency,Java,Multithreading,Concurrency,有没有一种方法可以安全地立即停止Java中线程的执行?特别是,如果Runnable实现的run()方法中的逻辑只执行一次迭代,并且没有定期检查任何指示停止的标志 我正在构建一个Web应用程序,用户可以使用它将整个文档的内容从一种语言翻译成另一种语言 假设文档非常大,并且随后假设每个翻译都需要很长时间(比如20-25分钟),我的应用程序会为每个由用户发起的翻译创建一个单独的线程。用户可以查看活动翻译的列表,并根据自己的意愿决定停止特定的翻译作业 这是我的Translator.java public

有没有一种方法可以安全地立即停止Java中线程的执行?特别是,如果
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.
   }

}
我创建了一个
translaterRunnable
类,它实现了
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
。这也是不可能的。执行器服务类的引用

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

我有什么选择

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

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

谢谢, 斯利拉姆

有没有一种方法可以安全地立即停止Java中线程的执行

否。每个线程都有责任定期检查它是否被中断以尽快退出

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;
    }
}
公共静态列表读取文件(字符串文件名)
{
列表记录=新的ArrayList();
尝试
{
BufferedReader reader=新的BufferedReader(新文件读取器(文件名));
弦线;
而((line=reader.readLine())!=null)
{
String[]split=line.split(\\s+);
records.addAll(Arrays.asList(split));
如果(需要停止){
break;//或抛出异常
}
}
reader.close();
退货记录;
}
捕获(例外e)
{
System.err.format(“尝试读取'%s',文件名时发生异常”);
e、 printStackTrace();
返回null;
}
}

您可以使用t.interrupt(),它不是那么简单,因为translate()方法依次调用许多其他类、方法和库,每一个类、方法和库加起来都可能会占用整个执行时间。因此,如果我希望我的应用程序在用户单击“停止”按钮时能够响应,我就不能这样做。代码中是否有任何部分需要很长时间,而您无法控制它,或者所有内容都在您的控制之下?translate()方法反过来调用执行大部分任务的库,而我无法控制它。在translate()方法中,除了调用这些库之外,我所做的就是更新翻译的状态(这是我唯一可以控制的地方),您可以将输入分块传递给这个库,而不是一次传递所有输入吗?