有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程使用复杂的子例程终止线程。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();  
        }   
    }
}

我怎样才能立即终止我的“连接”线程? 谢谢


共 (3) 个答案

  1. # 1 楼答案

    Java不久前放弃了线程中的stop()方法,因为不恰当地终止线程会在JVM中造成巨大的问题。从Javadoc for stop():

    Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.

    在大多数情况下,只要终止对您来说是安全的,您就可以检查threadTerminator变量,并优雅地处理线程退出。见http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

  2. # 2 楼答案

    你为什么不打断这根线,继续往前走,让它挂起来,直到它结束?用户可以在旧线程优雅地完成时启动不同的操作(线程)(顺便说一句,据我所知,您已经在做了很多事情)

    这样做的缺点是,当用户开始多次单击“connectToServer”(多个线程)或线程无法终止(挂起的线程)时,您会遇到问题。但也许对你来说就足够了

    编辑:
    实现一种机制来防止产生新的conthread是很简单的,除非“它很好用”(例如,使用信号量)

    棘手的部分将是决定是否打开一个新的连接。您可以询问原始线程(即有一个isalive()方法)或您试图连接的用户。或者你可以选择一个超时解决方案。例如,您可以让conthread更新一个时间戳,如果时间戳在1分钟内没有更新,则判断它已死亡。最普遍适用的解决方案可能是超时解决方案

  3. # 3 楼答案

    如果你正在做长时间的I/O,你可能会遇到麻烦。一些I/O操作会抛出InterruptedException,在这种情况下,您可以中断线程,并且,如果您在该I/O中,该异常将或多或少立即抛出,您可以中止并清理线程。因此,中断线程比使用特殊的自定义threadTerminator变量更可取——它更标准。在I/O之外的主代码中,定期检查interrupted()或isInterrupted()(而不是threadTerminator==false)

    如果您正在执行的I/O没有抛出InterruptedException,有时您可以关闭套接字或类似的,并捕获IOException。有时你会陷入困境