多线程使用复杂的子例程终止线程。JAVA
和其他许多人一样,我在不使用stop()终止线程时遇到问题。 我曾尝试在threads run()例程中对带有while循环的变量使用volatile
问题是,就我所知,while循环只在每次循环之前检查变量。Im运行的复杂例程需要很长时间,因此线程不会立即终止
我想要终止的线程是一个连接到另一台服务器的例程,它需要很长时间。我想要一个中止按钮。(终止线程)。我会用一些代码来解释
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();
}
}
}
我怎样才能立即终止我的“连接”线程? 谢谢
# 1 楼答案
Java不久前放弃了线程中的stop()方法,因为不恰当地终止线程会在JVM中造成巨大的问题。从Javadoc for stop():
在大多数情况下,只要终止对您来说是安全的,您就可以检查threadTerminator变量,并优雅地处理线程退出。见http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
# 2 楼答案
你为什么不打断这根线,继续往前走,让它挂起来,直到它结束?用户可以在旧线程优雅地完成时启动不同的操作(线程)(顺便说一句,据我所知,您已经在做了很多事情)
这样做的缺点是,当用户开始多次单击“connectToServer”(多个线程)或线程无法终止(挂起的线程)时,您会遇到问题。但也许对你来说就足够了
编辑:
实现一种机制来防止产生新的conthread是很简单的,除非“它很好用”(例如,使用信号量)
棘手的部分将是决定是否打开一个新的连接。您可以询问原始线程(即有一个isalive()方法)或您试图连接的用户。或者你可以选择一个超时解决方案。例如,您可以让conthread更新一个时间戳,如果时间戳在1分钟内没有更新,则判断它已死亡。最普遍适用的解决方案可能是超时解决方案
# 3 楼答案
如果你正在做长时间的I/O,你可能会遇到麻烦。一些I/O操作会抛出InterruptedException,在这种情况下,您可以中断线程,并且,如果您在该I/O中,该异常将或多或少立即抛出,您可以中止并清理线程。因此,中断线程比使用特殊的自定义threadTerminator变量更可取——它更标准。在I/O之外的主代码中,定期检查interrupted()或isInterrupted()(而不是threadTerminator==false)
如果您正在执行的I/O没有抛出InterruptedException,有时您可以关闭套接字或类似的,并捕获IOException。有时你会陷入困境