[英]Kill an uncooperative thread in Java
以下部分來自JUnit測試用例,該測試用例測試4種不同的Sorter
實現。 它調用了Sorter
具有的唯一方法Sorter
sort()
。
如果需要的時間超過2秒,我想要終止排序過程(因為我不關心任何需要超過2秒才能sort()
說500000 Integers
)。
我是新的Java多線程,在查看了所有其他線程( 如何殺死一個java線程?以及其他幾個)之后,我認為以下是我的問題的解決方案。 問題是,它是否能夠始終如一地運作,還是會出現任何問題? 我不關心數組或它的內容,因為reset()
會重置它的內容。
我稱之為不合作的原因是因為s.sort()
不受我的控制。
protected E[] arr;
@Test
public void testSortTArray() {
boolean allOk = true;
for (Sorter s : TestParams.getSorters()) {
System.out.println("Testing: " + s.getName() + " with " + arrayLenToTestWith + " elems of type "
+ classOfElemType.getName());
reset();
long startTime = System.nanoTime();
MyThread test = new MyThread(s, arr);
test.start();
try {
test.join(TestParams.getTimeThreshold());
} catch (InterruptedException e) {
e.printStackTrace();
}
if (test.isAlive())
test.interrupt();
if (!test.isInterrupted()) {
System.out.println("Time taken: " + ((System.nanoTime() - startTime) / (1000000)) + "ms");
if (!isSorted(arr)) {
allOk = false;
System.err.println(s.getName() + " didn't sort array.");
}
} else {
allOk = false;
System.err.println(s.getName() + " took longer than .");
}
}
assertTrue("At least one algo didn't sort the array.", allOk);
}
public class MyThread extends Thread {
private Sorter s;
private E[] arr;
public MyThread(Sorter s, E[] arr) {
this.s = s;
this.arr = arr;
}
@Override
public void run() {
s.sort(arr);
}
}
---編輯:回答---
基於每個人的評論:
Thread.interrupt()
不會掛起線程,它只是設置它的中斷狀態,如果沒有被線程的run()
實現檢查,它就沒用了。
Process
而不是Thread
。 一個Process
可以被殺死。
正如您可能從您提到的其他問題中看到的那樣,如果沒有它的合作就不可能可靠地停止Java線程,因為如果線程測試它(故意或無意),則interrupt()
ony可以工作。
但是,可以殺死進程 。 如果您在單獨的進程中生成每個排序算法,那么您可以強制終止它。
缺點是與進程交互比使用線程進行交互要困難得多,因為您沒有共享變量。
沒有線程的合作,沒有可靠和安全的方法來阻止它。 通過線程的協作,您可以使用它支持的機制中斷或停止線程。 線程只是不提供這種隔離......你必須使用多個進程。
這可能是Thread.stop()的一種情況。 盡管如此,請閱讀javadoc中的免責聲明:
不推薦 。 這種方法本質上是不安全的。 使用Thread.stop停止一個線程會導致它解鎖它已鎖定的所有監視器(這是未經檢查的ThreadDeath異常向上傳播的自然結果)。 如果先前受這些監視器保護的任何對象處於不一致狀態,則受損對象對其他線程可見,可能導致任意行為。 stop的許多用法應該被簡單修改某個變量的代碼替換,以指示目標線程應該停止運行。 目標線程應該定期檢查此變量,並且如果變量指示它將停止運行,則以有序的方式從其run方法返回。 如果目標線程等待很長時間(例如,在條件變量上),則應使用中斷方法來中斷等待。
它會一直工作,還是會有任何問題?
它可以工作,除了你需要正確處理線程中斷。 thread.interrupt()
僅在sort
方法支持時才有效。 我懷疑該方法不會調用Thread.sleep()
, wait()
或其他此類方法。 因此,它需要測試它是否在處理過程中被中斷:
while (!Thread.currentThread().isInterrupted()) {
// do sort stuff
}
如果不這樣做,那么中斷線程將不會停止處理。 我當然會添加另一個test.join();
在中斷之后,確保線程在您開始另一個排序操作之前完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.