[英]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.