Following piece is from a JUnit testcase that tests 4 different implementations of Sorter. It invokes the only method Sorter has viz sort().
I want to kill the sorting process if it takes longer than say 2 seconds (Because I don’t care for any implementation that takes longer than 2 seconds to sort() say 500000 Integers).
I’m new the Java multi-threading and after looking at all other threads ( How to kill a java thread? and a few others) on SO, I figured following as solution to my problem. Question is, would it work consistently, or could there be any issues? I don’t care abt the array or it’s contents as reset() would reset it’s contents.
Reason why I call it uncooperative is because s.sort() is out of my control.
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);
}
}
— edit: answer —
Based on comments from everyone:
- No. What I’m doing is not safe as
Thread.interrupt()will not suspend the thread, it’ll just set it’s interrupted state, which if not checked by the thread’srun()implementation, is useless.- In this case the next Sorter’s sort() would be called on the same array (which is still being sorted by the old “interrupted” thread), thus making things unsafe.
- One option is to create a separate
Processinstead of aThread. AProcesscan be killed.- Obviously the parameter passing isn’t easy in this case as it involves some IPC.
As you may have seen from the other questions you mention, it isn’t possible to reliably stop a Java thread without its cooperation, because
interrupt()ony works if the thread tests for it (deliberately or inadvertently).However, it is possible to kill a process. If you spawn each sorting algorithm in a separate process, then you can kill it forcibly.
The downside is that interacting with the process is significantly harder than interacting with a thread, since you don’t have shared variables.