和其他许多人一样,我在没有使用stop()的情况下杀死我的线程有问题。 我试图在我的线程run()例程中使用带有while循环的变量上的volatile。
问题是我可以看到,while循环只在每个回合之前检查变量。运行的复杂例程需要很长时间,因此线程不会立即终止。
我要终止的线程是一个连接到另一台服务器的例程,它使用的时间很长。我希望有一个中止按钮。 (终止线程)。我会尝试用一些代码来解释。
class MyConnectClass{
Thread conThread;
volitile boolean threadTerminator = false;
..some code with connect and abort button..
public void actionPerformed(ActionEvent e) {
String btnName = e.getActionCommand();
if(btnName.equalsIgnoreCase("terminate")){
threadTerminator = true;
conThread.interrupt();
System.out.println("#INFO# USER ABORTED CURRENT OPERATION!");
}else if(btnName.equalsIgnoreCase("connectToServer")){
conThread = new Thread() {
public void run() {
while(threadTerminator == false){
doComplexConnect(); //Uses a loooong time
}
}
}
conThread.start();
}
}
}
如何立即杀死我的“连接”线程? 感谢。
答案 0 :(得分:1)
Java在一段时间之后放弃了Threads中的stop()方法,因为杀死一个线程不合理地导致了JVM中的巨大问题。从Javadoc for stop():
使用Thread.stop停止一个线程会导致它解锁它已锁定的所有监视器(这是未经检查的ThreadDeath异常向上传播的自然结果)。如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为。 stop的许多用法应该被简单修改某个变量的代码替换,以指示目标线程应该停止运行。目标线程应该定期检查此变量,并且如果变量指示它将停止运行,则以有序的方式从其run方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。
在大多数情况下,只要您可以安全地终止,就可以检查threadTerminator var,并正常处理线程退出。见http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
答案 1 :(得分:1)
如果您正在进行长时间I / O,则可能遇到麻烦。一些I / O操作抛出InterruptedException,在这种情况下,你可以中断线程,而如果你在那个I / O中,那个异常会被抛出更多或者更少,你可以中止和清理线程。因此,中断线程比使用特殊的自定义threadTerminator变量更可取 - 它更标准。在I / O外部的主代码中,定期检查interrupted()或isInterrupted()(而不是threadTerminator == false)。
如果您正在执行不会抛出InterruptedException的I / O,有时您可以关闭Socket或类似的,并捕获IOException。有时候你被困住了。
答案 2 :(得分:1)
为什么不中断线程并继续前进,让它一直挂起直到它完成?用户可以在旧线程优雅地完成时启动不同的操作(线程)(从我看到你已经在做的事情已经完成了)
当用户开始大量点击“connectToServer”(许多线程)或者线程无法终止(被绞死的线程)时,你会遇到麻烦。但也许这对你的目的来说已经足够了?
编辑:
实现一种防止产生新的conthread的机制是很简单的,除非“它很好”(例如,使用信号量)。
棘手的部分是决定打开新连接是否合适。您可以询问原始线程(即具有isalive()方法)或您尝试连接的一方。或者您可以寻求超时解决方案。例如,如果时间戳没有更新1分钟等,你可以让conthread更新时间戳并确定它已经死了。最普遍适用的解决方案可能是超时解决方案。