我有一些执行器服务,它们安排本地任务,例如读取文件,连接到数据库等。这些进程执行大量的日志记录,这是基于有许多线程并发运行的事实,编写自己的东西进入日志。
现在,在某个时间点可以引发异常,该异常到达捕获所有异常的主要方法。然后我关闭所有服务并取消每个任务,希望阻止所有进一步的消息到日志。不幸的是,在关闭所有内容之后,这些消息仍然显示出来......有什么想法吗?
更新: 这是一些代码
public class Scheduler{
private final ExecutorService service;
private final ConcurrentMap<Object, Future<V>> cache;
...
public void shutDown() {
service.shutdownNow();
for (Future task : cache.values())
task.cancel(true);
}
答案 0 :(得分:7)
任务将继续运行,直到它到达检测到线程已被中断的程度。调用某些系统或线程函数时可能会发生这种情况,并且可能会抛出异常。在您的情况下,您可能需要通过调用
来检查自己 Thread.currentThread().isInterrupted()
如果您的代码运行循环并且您希望以这种方式停止,那么这样做是个好主意。
答案 1 :(得分:5)
当您shutdownNow
执行人或致电cancel(true)
时(顺便shutdownNow
已取消已提交的任务,因此您的循环不必要),您的任务就会中断。
根据他们对中断的反应,他们可能会:
例如,如果您的任务运行while(true)
循环,则可以将其替换为:
while(!Thread.currentThread().isInterrupted()) {
//your code here
}
cleanup();
//and exit
另一个例子:
for (int i = 0; i < aBigNumber; i++) {
if (Thread.currentThread().isInterrupted()) { break; }
//rest of the code for the loop
}
cleanup();
//and exit
另一个例子,如果你调用一个抛出InterruptedException的方法:
try {
Thread.sleep(forever); //or some blocking IO or file reading...
} catch (InterruptedException e) {
cleanup();
Thread.currentThread.interrupt();
//and exit
}
答案 2 :(得分:4)
执行者支持2种关闭方法
shutdown():启动有序关闭,其中先前提交的任务已执行,但不会接受任何新任务。如果已经关闭,调用没有额外的效果。
shutdownNow():尝试停止所有正在执行的任务,暂停等待任务的处理,并返回等待执行的任务列表。 除尽力尝试停止处理主动执行任务之外,没有任何保证。
参考:http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()
答案 3 :(得分:0)
- 尝试使用shutdowNow()
方法,它将关闭此执行程序抛出InterruptedException
,IO
和Synchronized operation
所启动的所有任务无法中断。
<强>例如强>
ExecutorService executor = Executors.newFixedThreadPool();
executor.execute();
...
...
executor.shutdownNow();
- cancel(true)
方法可与submit()
方法一起用于关闭特定任务。