当前位置: 首页 > 面试题库 >

正常关闭线程和执行程序

山越
2023-03-14
问题内容

下面的代码尝试做到这一点。

该代码将永远循环并检查是否有任何待处理的请求要处理。如果存在,它将创建一个新线程来处理请求并将其提交给执行者。一旦所有线程完成,它将休眠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将不会尝试关闭,因此不会调用关闭挂钩。

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



 类似资料:
  • 在一个实用程序库中,我正在创建一个执行器服务 然后,主线程将向该服务发布一些任务。当主线程完成时,我想关闭Executor服务,以允许应用程序退出。 问题是我只能更改实用程序库中的代码。我考虑的一个选项是使用守护线程。但在发布到该服务的任务完成之前,它会突然关闭。

  • 我像这样关闭了我的线程:thesensor.getlooper().quit();TheSensor.quit(); 但我还是得到了下面的错误。我需要做什么来忽略其余的消息?

  • 问题内容: 我目前在关闭应用程序的CTRL-C期间关闭异步协程时遇到问题。下面的代码是我现在所拥有的简化版本: 如果按CTRL-C,会给我以下输出: 我对asyncio的经验不是很丰富,所以我很确定我在这里缺少重要的东西。真正让我头疼的是输出之后的部分。从开始,我必须承认我不知道发生了什么。我查看了其他问题,但无法正常工作。那么,为什么这段代码输出类似的东西?如何干净地关闭协程呢? 谢谢你的帮助!

  • 问题内容: 我有一个Python程序,当我使用退出应用程序时 ,脚本不会关闭。我的过程仍显示在运行的过程中。 为什么python线程不能关闭? 问题答案: 您需要将该线程设为守护程序线程。为此,请在调用线程的init之后添加以下行 当只有守护程序线程处于活动状态时,程序将退出,主线程当然是非守护程序的

  • 好的,我正试图在Ecipse IDE中运行一个java程序,当我点击最上面一行的run按钮时,它正在运行其他程序(我愿意运行的程序甚至不在要运行的选项中),当我右键点击左列的类名(所有项目、类等都在这里)并点击“run as”时,我没有得到“1 java应用程序”选项,而是得到了“运行配置”选项。 有人能分享这个问题的解决方案吗? 这是我试图运行的代码:-

  • 我正在创建一个固定大小的线程池,包含10个线程,如下所示: 现在,在生成10个线程之后,每个线程都会执行一个runnable。这里的Runnable由工厂提供。得到() 现在,我想做一件事,一旦一个线程被关闭,也就是说,它完成了一个任务,它就会再次选择另一个runnable并开始运行它。因此,基本上检查所有10个线程的状态,并在线程关闭时再次执行runnable。 我知道我可以这样做,在其中我可以