2

好吧,我的视频转换器中有一个线程负责对视频进行转码。它是一个user threadsetDaemon(false).

为了停止它,我调用了该threadName.interrupt()方法,但是它并没有停止。它继续!
我该如何阻止它?
这是我尝试阻止它的方法:

if(getExecutingTaskID() == taskID){
         int what = JOptionPane.showOptionDialog(frame, 
                    "Do you want to interrupt an executing task?", 
                    "Task already running", 
                    JOptionPane.YES_NO_OPTION, 
                    JOptionPane.QUESTION_MESSAGE, 
                    null, null, null);
         if(what == JOptionPane.YES_OPTION){
             if(getExecutingTaskID() == taskID){
                 converter.interrupt();
             }
             return true;
         }
        }
        return false;
    }
4

3 回答 3

4

一个线程只有在调用一个抛出的方法InterruptedException或者它调用Thread.interrupted并被编码来响应它时才能被中断。如果您希望能够随时中断线程,则需要将其构建到代码本身中。Oracle 提供了教程。基本上,您的选择是使用抛出InterruptedExcetion类似sleepor的方法wait,定期调用Thread.interrupted,或者拥有您自己的停止变量,您可以定期检查。

不管你怎么分片,你都必须实现中断。Java 只是有一些简单的方法可以将消息传递给线程。

有一种Thread.stop方法,但这种方法被认为是极其危险的。这会停止线程并立即释放所有锁,这可能会使对象处于不可用状态。使用它通常只是一个坏主意。

(很抱歉对答案进行了重大修改。)

于 2013-05-25T06:08:40.283 回答
3

引用Java教程(强调我的):

“中断是对线程的指示,它应该停止正在做的事情......”
“由程序员决定线程如何准确响应中断......”
“为了使中断机制正常工作,被中断的线程必须支持它自己的中断......”

本质上,您必须在线程内观察“中断”标志,并在检测到已设置标志时“从内部”终止它。有几种方法可以检查和处理中断(请参阅上面的链接) - 例如,您可以使用Thread's interrupted() method

我不知道您的读者和转换器的内部运作,但这while-loop似乎是实施检查的一个很好的候选人:

while (reader.readPacket() == null) { 
    // code the next packet
    ...
    // Check for interruption
    if (Thread.interrupted()) {
       // We've been interrupted: terminate
       return;
    }
}
于 2013-05-25T06:26:36.477 回答
2

有 3 种方法可以终止线程:

  1. 线程已经完成了它设计的工作,并且自然地退出了 run() 方法。
  2. 线程在工作时收到了中断信号。它决定不继续工作并退出 run() 方法。它也可能决定忽略该信号并继续工作。
  3. 该线程已被标记为守护线程。当创建该线程的父线程终止时,该线程将被JVM强制终止。

请参阅 Sun 的此线程,了解他们为什么不推荐使用 Thread.stop()。它详细介绍了为什么这是一种不好的方法以及应该如何安全地停止线程。

http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

他们推荐的方式是使用共享变量作为要求后台线程停止的标志。然后可以由请求线程终止的不同对象设置此变量。

于 2013-05-25T06:39:51.057 回答