正确关闭线程和执行程序 [英] Graceful shutdown of threads and executor

查看:145
本文介绍了正确关闭线程和执行程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面这段代码试图对此进行说明。



代码永远循环并检查是否有待处理的待处理请求。如果有,则创建一个新线程来处理请求并将其提交给执行程序。完成所有线程后,它会休眠60秒并再次检查待处理的请求。

  public static void main(String a []){
//变量init代码省略
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();
长名;
try {
name = f.get();
LOGGER.debug(名称+已完成);
} catch(ExecutionException e){
LOGGER.error(e.toString());
}
} catch(InterruptedException e){
LOGGER.error(e.toString());
}
}
TimeUnit.SECONDS.sleep(60);
}

}

我的问题是大多数处理由这些线程完成处理数据库。这个程序将在Windows机器上运行。当有人试图关闭或注销机器时,这些线程会发生什么。如何正常关闭正在运行的线程以及执行程序。?

解决方案

ExecutorService的典型有序关闭可能看起来像这样:

 最终ExecutorService执行者; 

Runtime.getRuntime()。addShutdownHook(new Thread(){
public void run(){
executor.shutdown();
if(!executor。 awaitTermination(SHUTDOWN_TIME)){//可选*
Logger.log(Executor未在指定时间内终止。); //可选*
列表< Runnable> droppedTasks = executor.shutdownNow() ; //可选**
Logger.log(Executor突然关闭。+ droppedTasks.size()+任务将不会被执行。); //可选**
}
}
});

*您可以记录执行者在等待您愿意等待的时间后仍有待处理的任务。$
**您可以尝试强制执行者的工作线程放弃他们当前的任务,并确保他们不启动剩余的任务。



<请注意,当用户向 java 进程发出中断或仅在 ExecutorService 时发出中断时,上述解决方案将起作用包含守护程序线程。相反,如果 ExecutorService 包含尚未完成的非守护程序线程,则JVM将不会尝试关闭,因此不会调用关闭挂钩。



如果尝试将进程作为离散应用程序生命周期(而非服务)的一部分关闭,则不应将关闭代码放在关闭挂钩内但位于适当的位置该计划旨在终止。


The following piece of code tries to accompolish this.

The code loops forever and checks if there are any pending requests to be processed. If there is any, it creates a new thread to process the request and submits it to the executor. Once all the threads are done,it sleeps for 60 seconds and again checks for pending requests.

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);
    }

  }

My question is most of the processing done by these threads deal with database. And this program will run on a windows machine. What happens to these threads when someone tries to shutdown or logoff the machine.? How to gracefully shutdown the running threads and also the executor.?

解决方案

A typical orderly shutdown of an ExecutorService might look something like this:

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 **
        }
    }
});

*You can log that the executor still had tasks to process after waiting the time you were willing to wait.
**You can attempt to force the executor's worker Threads to abandon their current tasks and ensure they don't start any of the remaining ones.

Note that the solution above will work when a user issues an interrupt to your java process or when your ExecutorService only contains daemon threads. If, instead, the ExecutorService contains non-daemon threads that haven't completed, the JVM won't try to shutdown, and therefore the shutdown hooks won't be invoked.

If attempting to shutdown a process as part of a discrete application lifecycle (not a service) then shutdown code should not be placed inside a shutdown hook but at the appropriate location where the program is designed to terminate.

这篇关于正确关闭线程和执行程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆