下面的代码试图实现这一点。
该代码永远循环并检查是否有任何待处理的请求。如果有,它会创建一个新线程来处理请求并将其提交给执行器。所有线程完成后,它会休眠 60 秒,并再次检查待处理的请求。
public static void main(String a[]){
//variables init code omitted
ExecutorService service = Executors.newFixedThreadPool(15);
ExecutorCompletionService<Long> comp = new ExecutorCompletionService<Long>(service);
while(true){
List<AppRequest> pending = service.findPendingRequests();
int noPending = pending.size();
if (noPending > 0) {
for (AppRequest req : pending) {
Callable<Long> worker = new RequestThread(something, req);
comp.submit(worker);
}
}
for (int i = 0; i < noPending; i++) {
try {
Future<Long> f = comp.take();
long name;
try {
name = f.get();
LOGGER.debug(name + " got completed");
} catch (ExecutionException e) {
LOGGER.error(e.toString());
}
} catch (InterruptedException e) {
LOGGER.error(e.toString());
}
}
TimeUnit.SECONDS.sleep(60);
}
}
我的问题是这些线程完成的大部分处理都涉及数据库。这个程序将在Windows机器上运行。当有人尝试关闭或注销机器时,这些线程会发生什么?如何优雅地关闭正在运行的线程以及执行器?
ExecutorService 的典型有序关闭可能如下所示:
final ExecutorService executor;
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIME)) { //optional *
Logger.log("Executor did not terminate in the specified time."); //optional *
List<Runnable> droppedTasks = executor.shutdownNow(); //optional **
Logger.log("Executor was abruptly shut down. " + droppedTasks.size() + " tasks will not be executed."); //optional **
}
}
});
*您可以记录执行者在等待您愿意等待的时间后仍有任务要处理。
**您可以尝试强制执行程序的工作线程放弃当前任务,并确保它们不会启动任何剩余的任务。
请注意,当用户向您的系统发出中断时,上述解决方案将起作用。java
过程或当你的ExecutorService
仅包含守护线程。相反,如果ExecutorService
包含尚未完成的非守护线程,JVM 不会尝试关闭,因此关闭挂钩不会被调用。
如果尝试关闭进程作为离散应用程序生命周期(而不是服务)的一部分,则关闭代码不应放置在关闭挂钩内,而应放置在程序设计为终止的适当位置。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)