簡體   English   中英

中斷/殺死正在運行的線程

[英]Interrupt / Kill a running thread

在發生特定超時時,我需要殺死/取消/中斷/失敗正在運行的線程。 我使用ExecutorService來管理一個線程池,通過它我可以使用Future的cancel()方法取消該任務,該方法從ExecutorService的視圖中刪除它,但線程本身繼續運行。

在線查看,人們談論使用isInterrupted()方法中斷具有循環的線程 ,或者正在等待可以通過顯示InterruptedException來處理的IO。

殺死沒有循環(或有任何其他掛鈎)並且不等待IO的線程的一般做法是什么? 環顧四周,Thread.stop()似乎做我需要的東西(只是盲目地殺死線程),但不建議使用它。

如果您使用ExecutorService那么您不應該亂用它的線程:這個概念隱藏在執行程序后面,這是一個比線程更高級別的概念,因此不提供管理它們的方法。 我強烈建議你停止整個Executor而不是試圖阻止它的一個線程。

請注意, ExecutorService中的線程正在循環,它們的循環包括等待任務在其任務隊列中可用。

Java中沒有簡單的方法來阻止沒有循環的線程,你可以做的是:

  • 有一個易失性布爾標志,線程的Runnable從時間檢查它是否應該停止(可以用作線程循環中的條件的相同標志)。
  • 調用Thread.interrupt()來嘗試(盡力而為,如果你不知道自己在做什么就非常不安全)停止與同步相關的wait / lock / aquire / ...線程被卡住了。

我個人建議你去中斷路線,因為它是最干凈的方式和結束該線程的優雅方式。

讓我們試着很好地定義我們的目標。 一個線程只是一個單獨的進程,可以執行一組您指定要執行的任務。 可能您必須在代碼中找到可中斷點,並且必須在這些點上進行中斷()檢查。 顯然,這些要點應該達到邏輯結局。

例如,

public void run(){
      if (Thread.currentThread().interrupted()) {
           return;
      }
      //LogicA start
      //LogicA end
      if (Thread.currentThread().interrupted()) {
           return;
      }
      //LogicB start
      //LogicB end
      if (Thread.currentThread().interrupted()) {
           return;
      }
      //LogicLong start
      //Long code here cannot end or exit or kill the thread now. Let it finish
      //LogicLong ends
      if (Thread.currentThread().interrupted()) {
           return;
      }
      //LogicD start
      //LogicD end
}

如果您已經擁有Executorservice那么您已經收到了Future 因此,取消作業的唯一理智和干凈的方法是調用future.cancel(boolean mayInterruptIfRunning) 設置mayInterruptIfRunning將在當前正在運行的情況下中斷作業,如果作業未運行則不執行任何操作。 所以你只需要通過Thread.interrupted()檢查Thread.interrupted()來編寫工作來尊重中斷。

請注意作業主題之間的區別。 您提交作業 ,因此,你不應該試圖規避與線程渣土ExecutorService可能在所有關於那個被逗樂沒有。 調用Future.cancel(true)您可以向所有相關方發出干凈的信號,告訴您該怎么做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM