2012-01-22 59 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

相關問題