5

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

假设我正在运行一个线程,它只是跟踪事物运行了多长时间以及它们是否超过了某个阈值,这是否是杀死 executorservice 和所有正在运行的线程的好方法?

思维过程示例:

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 次运行,并且仅在我不工作的一天中的某些时间)。

4

2 回答 2

4

这就是我会做的

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() 。
  • 如果一个任务忽略了中断(),它可能表现不佳,这可能会使堆处于损坏状态。
  • 调用 stop() 应该停止任务,但不会停止线程池线程,除非它已经被shutdown()捕获。(诚​​然,很容易解决)
于 2012-10-18T13:33:58.480 回答
4

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

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

  • 正确处理InterruptedExceptions。

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


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

Thread.stop()方法已被弃用,因为它从根本上是不安全的。停止一个线程可能会使关键数据结构处于中间状态,并且可能会干扰以各种方式与其交互的其他线程。理论上是可以stop安全使用的,但是很难制定出一套足以保证没有坏事发生的通用前提条件。

于 2012-10-18T13:37:34.923 回答