[英]What is the safest/best way to stop a thread and run some clean-up code
作为用Java实现语音识别程序的一部分,我在单独的线程中实现了实际的语音识别代码。 当识别到单词时,主线程处理GUI界面并从语音识别线程接收不断的更新。
当用户单击主线程上GUI中的“退出”按钮时,我希望该线程立即运行一些清理代码并终止。
我目前有以下内容:
public class VoiceRecognitionCore extends SwingWorker<List<String>, String>
{
//Variables and things here
@Override
public List<String> doInBackground() throws VoiceRecognitionException
{
//Code here
while(continueVoiceRecog == true)
{
//More code
Result result = recog.recognize();
//More code
}
}
}
我依靠while循环不断检查continueVoiceRecog的状态,当用户单击“退出”时,该状态将由主线程设置为false。
当前的问题是该代码有时可以永久地放置在recog.recognize()方法中,因此它永远都不会回到while检查中。 应当指出,这始终是一个临时解决方案。
我正在考虑扩展doInBackground()以捕获InterruptedException,并将使用线程中断,该线程中断将调用清除方法来释放正在使用的任何资源。
在这种情况下最安全/最佳的方法是什么? 如果这是我的建议,那么我应该注意任何潜在的问题吗?
使用线程中断是完全可以接受的途径-但是,在您的示例(使用SwingWorker
)中,可以使用cancel()
方法代替。
创建VoiceRecognitionCore
后,在调用代码中可以cancel()
工作者退出按钮动作侦听器:
final VoiceRecognitionCore worker = new VoicRecognitionCore();
worker.execute();
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// True passed to Interrupt the underlying thread.
worker.cancel(true);
// other clean-up
// then System.exit(0); ?
}
});
但是,这种方法将需要检查的状态:Thread.isInterrupted你的()内recognize()
方法。 (请参阅链接: http : //docs.oracle.com/javase/tutorial/uiswing/concurrency/cancel.html )
如果您需要清理东西并且没有能力检查isInterrupted()
标志-也许最好的方法是拥有一种方法来确定您的recog
对象是否在中间识别...以及何时退出按下按钮-如果recog.isRecognizing()
然后进行清理然后退出?
PS。 有人可能会争辩说,如果您正在执行System.exit(0); 无论如何,然后干净地退出该循环也许是不必要的……但这取决于您是否在其中进行其他清理……例如完成对文件的写入等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.