我有一份提交给ExecutorService
的任务列表。但是我需要在截止时间凌晨2:30之前关闭ExecutorService,即使任务没有完成。我怎样才能做到这一点?我检查了API,只有下面的方法:
ExecutorService exec = //...
exec.awaitTermination(100, TimeUnit.MILLISECONDS);
但是如何使以下块以原子方式执行?也就是说,我该如何避免差距呢?例如:
long timeDiff= calculate(now, deadline);
// Gap: assuming current thread does not have chance to run for 10 minutes...
exec.awaitTermination(timeDiff, TimeUnit.MILLISECONDS);
感谢。
答案 0 :(得分:2)
你可能并不是指'原子',我认为你的意思是“毫不拖延”。因此,在调用timeDiff
时,exec.awaitTermination()
仍然是正确的。
我认为这是正确的,所以答案是:你不能。
如果您对细节感兴趣: 您的Java代码被转换为Java Bytecodes,这些由JVM执行,JVM是在您的操作系统上运行的常规进程。而且你根本无法阻止操作系统中断线程(我假设您使用具有抢占式多任务处理的操作系统(每个UNIX(包括Linux和Mac OS X),Windows 95或更高版本,...))。
即使您可以在一个Java字节码中完成所有操作,它仍然无法正常工作,因为操作系统可能会在一个Java字节码中间打断您。
即使是awaitTermination(Date deadline)
方法也无济于事。它也必须由某人实施。
您可以做的最好的事情是尽可能少的字节码。
如果我是你,我可能就像你的代码一样。
然而,可以更准确一些:
Date deadline = ....;
final TimerTask stopTask = new TimerTask() {
public void run() {
exec.shutdownNow();
}
};
new Timer().schedule(stopTask, deadline);
但正如我所说:shotdownNow()
没有真正的保证deadline
立即执行。实际上,在真正的截止日期之前将deadline
设置为1秒应该没问题: - )
答案 1 :(得分:1)
在另一个高优先级线程(或计时器)中等待截止日期并致电exec.shutdownNow()