用Java杀掉一个不合作的线程

时间:2012-09-21 19:17:44

标签: java multithreading kill interrupt

以下部分来自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()实现检查,它就没用了。
    • 在这种情况下,下一个Sorter的sort()将在同一个数组上调用(仍然由旧的“中断”线程进行排序),从而使事情变得不安全。
  • 一种选择是创建单独的Process而不是Thread。可以杀死Process
    • 显然,在这种情况下参数传递并不容易,因为它涉及一些IPC。

4 个答案:

答案 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();,以确保在开始另一个排序操作之前线程完成。