以下部分来自JUnit测试用例,该测试用例测试Sorter
的4种不同实现。它调用唯一的方法Sorter
具有sort()
。
如果需要的时间超过2秒,我想要终止排序过程(因为我不关心任何花费超过2秒到sort()
说500000 Integers
)的实现。< / p>
我是新的Java多线程,在查看了所有其他线程(How to kill a java thread?和其他几个)之后,我认为以下是我的问题的解决方案。 问题是,它是否会一致地工作,或者是否会出现任何问题?我不关心数组或其内容,因为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
。
答案 0 :(得分:3)
正如您可能从您提到的其他问题中看到的那样,如果没有它的合作就不可能可靠地停止Java线程,因为interrupt()
ony在线程测试它时(故意或无意)。
但是,可以杀死process。如果你在一个单独的进程中产生每个排序算法,那么你可以强行杀死它。
缺点是与流程交互要比使用线程进行交互要困难得多,因为你没有共享变量。
答案 1 :(得分:3)
没有线程的合作,就没有可靠而安全的方法来阻止它。通过线程的协作,您可以使用它支持的机制中断或停止线程。线程只是不提供这种隔离......你必须使用多个进程。
答案 2 :(得分:3)
这可能是Thread.stop()的情况。请阅读javadoc中的免责声明,特别是:
<强>已过时即可。这种方法本质上是不安全的。使用Thread.stop停止一个线程会导致它解锁它已锁定的所有监视器(这是未经检查的ThreadDeath异常向上传播的自然结果)。如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为。 stop的许多用法应该被简单修改某个变量的代码替换,以指示目标线程应该停止运行。目标线程应该定期检查此变量,并且如果变量指示它将停止运行,则以有序的方式从其run方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。
答案 3 :(得分:2)
它会一直运作,还是会有任何问题?
除了你需要正确处理线程中断之外它会工作。 thread.interrupt()
仅在sort
方法支持时才有效。我怀疑该方法不会调用Thread.sleep()
,wait()
或其他此类方法。因此,它需要测试它是否在处理过程中被中断:
while (!Thread.currentThread().isInterrupted()) {
// do sort stuff
}
如果不这样做,那么中断线程将不会停止处理。我肯定会在中断后添加另一个test.join();
,以确保在开始另一个排序操作之前线程完成。