2012-01-22 53 views
3

我写过类VideoProcessor,它对视频进行了一些重处理。如果“启动”,则会创建一个新线程,并将该参考保存在 videoProcessingThread的字段中。现在的问题是:调用线程上的中断(),但它永远不会中断

videoProcessingThread.interrupt(); 

这似乎没有任何作用,因为isInterrupted()永远不会计算为true。我也加了其他中断检查,只是为了确定;但他们也不“工作”。我已经实施了一种解决方法:

videoProcessingThread.kill(); 

这似乎实际上是“杀死”线程。方法kill将布尔变量 kill设置为true,并且正确计算并且线程返回。

videoProcessingThread = new Thread() { 
    boolean kill = false; // workaround 

    public void run() { 
     // init stuff 
     while (currentFrameIndex < totalFrames) { 
      if (isInterrupted()) { 
       System.out.println("isInterrupted"); 

       return; 
      } 
      if (Thread.interrupted()) { 
       System.out.println("interrupted"); 

       return; 
      } 
      if (Thread.currentThread().isInterrupted()) { 
       System.out.println("Thread.currentThread().isInterrupted()"); 

       return; 
      } 
      if (kill) { 
       System.out.println("killed"); 

       return; 
      } 
     } 
     // heavy processing 
    } 

    public void kill() { 
     kill = true; 
    } 
} 

我在做什么错?

+1

您评论http://stackoverflow.com/questions/8627719/interrupt-doesnt-work? – ziesemer

+0

是重处理(或称为那里的任何方法)捕获InterruptedException或检查中断标志? –

+0

如何调用由匿名类声明的方法?换句话说,'videoProcessingThread'是Thread,它没有kill方法。你怎么称呼它?切线位,但只是好奇。 – erickson

回答

1

首先,拨打interrupt()可能实际上并没有设置中断状态,请参阅here in javadocs的确切条件,有时候它只会丢一个InterruptedException

其次,实际调用interrupted()方法也会明确除了它返回中断状态,所以isInterrupted()下次调用(只返回当前状态,但不明确的话)可能不会做你期望。

使用布尔变量可能不是一个不错的方法来完成这一点。您可以阅读this article,其中会详细说明当您尝试中断某个线程以及如何可靠地进行线程时发生的情况。

1

您的kill不保证能够正常工作,除非它不稳定。

只有在调用检查该标志的操作时才中断线程。如果您拨打电话,某些NIO操作会抛出异常interrupt()

大多数情况下使用interrupt()与设置易失性标志相同。即您的任务需要定期检查。杀死线程的唯一安全方法是在自己的进程中运行它。

如果你有一个线程是一个Actor(它只修改线程本地内存),你可以考虑使用stop()。它的主要问题是你可以让内存线程修改为不一致的状态。如果你隔离该线程的内存并放弃它,如果线程停止这应该工作正常。

+0

+1,我的想法正好。为什么这是downvoted? – Tudor

+1

@Tudor,也许是因为我提到了停止使用(),但这并不意味着如果你知道自己在做什么,就不能使用它。 –

+1

我同意stop()在大多数情况下是一个糟糕的主意,但是如果线程执行的代码没有办法导致不一致的状态,那么我也没有看到问题。 – Tudor

相关问题