用复杂的子程序杀死一个线程。 Java的

时间:2012-02-06 04:44:17

标签: java multithreading abort

和其他许多人一样,我在没有使用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();  
        }   
    }
}

如何立即杀死我的“连接”线程? 感谢。

3 个答案:

答案 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更新时间戳并确定它已经死了。最普遍适用的解决方案可能是超时解决方案。