2017-09-05 66 views
2

感覺愚蠢不知何故,因爲我現在正試圖爲一個線程在groovy工作幾個小時已經有一個簡單的中斷。Java線程中斷不適用於我(groovy)

不知怎的,下面的代碼不會在線程'名稱'中設置'中斷'標誌。導致循環運行直到結束。

發現噸其他問題,其中通常檢查Thread.currentThread().isInterrupted()缺失。但是,這是不是這裏的情況:

def t = Thread.start('name') { 
    try { 
     for (int i = 0; i < 10 && !Thread.currentThread().isInterrupted(); ++i) { 
      println "$i" 
      sleep 1000 
     } 
    } catch (InterruptedException e) { 
     println "Catched exception" 
     Thread.currentThread().interrupt(); 
    } 
} 
println "Interrupting thread in 1..." 
sleep 1000 
println "Interrupting thread..." 
t.interrupt() 
sleep 2000 

我獲得以下輸出

Interrupting thread in 1... 
0 
Interrupting thread... 
1 
2 
3 
4 
5 
6 
7 
8 
9 

不知道我錯過這裏/做錯了嗎? 也嘗試使用ExecutorService並在返回的Future上調用cancel(true)。也沒有工作。

回答

3

TL; DR:不要使用Thread中斷作爲中止標準,而是用一些自定義的標誌來代替。


您沒有使用Thread.sleep()這將拋出InterruptedException,但GDKS Object.sleep()負責處理,而忽略中斷:http://docs.groovy-lang.org/docs/groovy-2.4.7/html/groovy-jdk/java/lang/Object.html#sleep(long)

要麼使用Thread.sleep(),而不是像:(打斷catch塊是沒用的,你的情況)

def t = Thread.start('name') { 
    try { 
     for (int i = 0; i < 10 && !Thread.interrupted(); ++i) { 
      println i 
      Thread.sleep 1000 
     } 
    } catch (InterruptedException e) { 
     println "Catched exception" 
    } 
} 
println "Interrupting thread in 1..." 
sleep 1000 
println "Interrupting thread..." 
t.interrupt() 

或使用Object.sleep()變異與Closure並中止你的循環在那裏,E。 G。通過投擲InterruptedException像:

def t 
t = Thread.start('name') { 
    try { 
     for (int i = 0; i < 10 && !Thread.interrupted(); ++i) { 
      println i 
      sleep(1000) { 
       throw new InterruptedException() 
      } 
     } 
    } catch (InterruptedException e) { 
     println "Catched exception" 
    } 
} 
println "Interrupting thread in 1..." 
sleep 1000 
println "Interrupting thread..." 
t.interrupt() 

已經解決你的困惑,現在讓我建議不要做你正在嘗試做的。中斷是沒有辦法用作中止條件的好方法。睡眠或阻塞IO總是可能由於各種原因而中斷。更好的方法是讓你的運行循環檢查一些boolean標誌,你切換到中止工作。

+0

感謝您的詳細解釋。應該注意到,首先我使用自定義標誌來工作;然而,在搜索網絡後,我發現很多帖子說明應該使用內置的中斷功能來停止執行線程。但可能只是爲了Java。只是爲了澄清一下:我不會因爲同一個線程寫入同一個線程而在另一個線程中讀取同步而遇到麻煩? –

+0

Java或Groovy在這裏沒有區別。我的建議實際上是針對Java的,但對於Groovy而言,它建立在Java之上的確如此。實際上,儘可能使用執行程序和任務,而不是線程,因爲它們經過了徹底的編寫和測試。但是,是的,您必須同步對該標誌變量的訪問,以便能夠從多個線程安全地修改和訪問它。 – Vampire

4

如果在中斷線程的同時sleep ing,睡眠中斷線程catchesInterruptedExceptionThread.sleep拋出並且中斷狀態被清除。所以你的Thread.currentThread().isInterrupted()總是返回false

如果您將sleep 1000替換爲Thread.sleep(1000),則可以使代碼正常工作。