到目前为止,在我使用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次运行,并且只在我不工作的那一天的某些时间)。
答案 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()的原因
shutdown()
。 (不可否认,易于解决)