如果特定线程运行的时间太长,我可以使用executorservice来杀死它吗?

时间:2012-10-18 13:30:05

标签: java multithreading interrupt executor

到目前为止,在我使用executorservice的实验中,我有很多建议涉及使用future.get,然后是future.cancel,以便抛出一个线程中断,然后需要在线程中捕获,并处理那里。我的问题有点不同。

假设我正在运行一个线程,它只是跟踪事情的运行时间以及它们是否超过某个阈值,这是否是一种杀死执行器服务和所有正在运行的线程的好方法?

思考过程示例:

ExecutorService threadPool = Executors.newFixedThreadPool(12);
timekeeper.start();
List<Future<?>> taskList = new ArrayList<Future<?>>();
    for (int i = 0; i < objectArray.length; i++) {
        Future<?> task = threadPool.submit(new ThreadHandler(objectArray[i], i));
        taskList.add(task);
        Thread.sleep(500);
    }

if(timekeeper.now() > 60)
    threadpool.shutdownNow();
}

这会有用吗?我无法检查,因为我的线程很少失败(大约1/700次运行,并且只在我不工作的那一天的某些时间)。

2 个答案:

答案 0 :(得分:4)

shutdownNow方法尝试中断所有活动任务线程,这只有在任务被编码为受尊重的中断时才有效。他们需要:

  • 检查在长时间运行的循环中是否设置了中断标志,

  • 正确处理InterruptedException

基本上,任务需要配合中断才能工作。如果它们不合作,除了退出JVM之外,没有安全可靠的方法来阻止它们。


  

上面有人提到.stop()方法作为评论,你能不能提一下为什么这会是一个坏主意?

Thread.stop()方法为deprecated,因为它基本上不安全。停止线程可以使关键数据结构处于中间状态,并且可以以各种方式干扰与其交互的其他线程。从理论上讲,可以安全地使用stop,但很难找出足以确保不会发生任何不良事件的一组一般先决条件。

答案 1 :(得分:3)

这就是我要做的事情

ExecutorService threadPool = Executors.newFixedThreadPool(12);
List<Future<?>> taskList = new ArrayList<Future<?>>();
for (int i = 0; i < objectArray.length; i++) {
    taskList.add(threadPool.submit(new ThreadHandler(objectArray[i], i)));
threadPool.shutdown();
threadPool.awaitTermination(60, TimeUnit.SECONDS); // or what ever
threadPool.shutdownNow();

这假定您的任务将遵循中断。如果他们不这样做就没有杀死线程的干净方法(除了使用一个非常相同的标志)


不在此处使用Thread.stop()的原因

  • 您无权访问Thread对象以调用stop()。
  • 如果一个任务忽略了interrupt(),它可能表现不佳,这可能会使堆处于损坏状态。
  • 调用stop()应该停止任务但不会停止线程池线程,除非它陷阱shutdown()。 (不可否认,易于解决)