Java-如何从GUI安全地停止Web应用程序中的线程?
有没有一种方法可以安全地立即停止Java中线程的执行?特别是,如果Java-如何从GUI安全地停止Web应用程序中的线程?,java,multithreading,concurrency,Java,Multithreading,Concurrency,有没有一种方法可以安全地立即停止Java中线程的执行?特别是,如果Runnable实现的run()方法中的逻辑只执行一次迭代,并且没有定期检查任何指示停止的标志 我正在构建一个Web应用程序,用户可以使用它将整个文档的内容从一种语言翻译成另一种语言 假设文档非常大,并且随后假设每个翻译都需要很长时间(比如20-25分钟),我的应用程序会为每个由用户发起的翻译创建一个单独的线程。用户可以查看活动翻译的列表,并根据自己的意愿决定停止特定的翻译作业 这是我的Translator.java public
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()方法中,除了调用这些库之外,我所做的就是更新翻译的状态(这是我唯一可以控制的地方),您可以将输入分块传递给这个库,而不是一次传递所有输入吗?