当前位置: 首页 > 知识库问答 >
问题:

当执行者服务时。关机();应该叫

樊博雅
2023-03-14

我们有一个服务方法GetDataParallel(),目前可能被许多客户机调用,我们使用ExecutorService在其中调用MyCallable。但是我找到了除非我打电话给执行者服务。关机();应用程序永远不会退出,所以为什么应用程序不能退出,我们必须在应用程序退出之前手动关闭所有线程池线程?在服务环境中,我认为我们不需要呼叫执行器服务。关机();让应用程序继续运行,对吗?

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MultiThreading {

    static ExecutorService executorService = Executors.newFixedThreadPool(100);
    private List<String> _BusinessUnits= new ArrayList<String>();
    public static void main(String[] args) throws Exception {

        MultiThreading  kl =new MultiThreading();
        kl.GetDataParallel();
        Thread.sleep(10000);
        System.out.println("111111111");
         //executorService.shutdown();

    }

    public   void GetDataParallel( ) throws Exception
    {
        _BusinessUnits.add("BU1");
        _BusinessUnits.add("BU2");
        _BusinessUnits.add("BU3");

        for(final String v : _BusinessUnits)
        {
            ExecutorServiceTest.executorService.submit( new MyCallable());
        }
    }
}

  class MyCallable implements Callable  {
    @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        //return the thread name executing this callable task
        System.out.println(Thread.currentThread().getName());
        return Thread.currentThread().getName();
    }
}

共有3个答案

聂和宜
2023-03-14

在应用程序环境中,您必须调用shutdown以确保由ExecutorService启动的线程必须停止,并且它不应接受任何新任务。否则JVM将不会退出。

如果是服务,您应该在停止服务执行之前调用shutdown。例如,对于web应用程序,ServletContextListenercontextDestroyed方法可用于调用ExecutorServiceshutdown方法。这将确保在突然终止申请之前必须完成任何现有任务,但不会接受任何新任务进行处理。

呼延永新
2023-03-14

Java中有两种类型的线程(当然取决于您如何看待它们)。“用户”线程和“守护进程”线程。您的应用程序在以下情况之一结束:

  1. 你调用System.exit()
  2. 您的应用程序中没有User线程。这在这里解释。

请注意,main函数是由JVM在“用户”线程上执行的,这意味着只要尚未完成main函数。大多数多线程应用程序只会运行main函数来启动所需的所有线程。

守护进程线程背后的想法是,您可以(定期)做一些事情,但如果所有其他任务都完成了,它将不会阻止应用程序退出。

默认情况下,新线程是“非守护进程”线程,这同样适用于您的ExecutorService所包含的线程。如果要更改此设置,必须创建自己的ThreadFactoryThreadFactory允许您手动为ExecutorService创建线程,当ExecutorService需要新线程时,将调用它。下面是一个创建“守护进程”线程的示例:

public class DaemonThreadFactory implements ThreadFactory
{

    @Override
    public Thread newThread(final Runnable r)
    {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
}

然后可以通过创建执行器服务来使用它:

ExecutorService service = Executors.newFixedThreadPool(100, new DaemonThreadFactory());

请注意,这也是为线程提供自定义名称的方法,这非常有用,因为许多日志框架都会记录线程名称(调试器会显示)。

如果要这样做,在应用程序中,它会立即退出,因为您只创建“守护进程”线程,所以您必须要么让另一个线程保持活动状态(这可以由另一个框架隐式完成,例如,如果您有GUI)。

另一种方法是手动调用系统。退出()。通常调用系统。不建议在代码中退出()。主要是因为它不允许良好的重构、重用、测试和许多退出点,所以应用程序无法预测。为了避免这些问题,可以创建一个回调函数来处理作业完成事件。在这个应用程序中,您可以调用系统。exit(),测试代码或其他应用程序可以执行其他操作。

朱毅
2023-03-14

通常在应用程序退出时关闭ExecutorService——大多数应用程序都有某种生命周期和关闭顺序。如果您希望应用程序在主线程完成所有必须完成的工作时退出,那么您希望在其工作完成时关闭它(这意味着有一个定义良好的点,它的工作完成了,您可以知道什么时候完成)。

服务器端框架通常有一些生命周期方法,您可以将其挂接,以检测代码何时被关闭并干净地退出。或者,您可以使用VM关闭挂钩(可能是为了延迟关闭,直到所有当前排队的作业完成),这样无论是什么代码导致程序退出,您的清理代码都将运行。

一般来说,如果框架没有提供一个明确定义的退出点,那么创建一个明确定义的退出点是个好主意——它可以让您拥有一个可以干净卸载的应用程序(也许,用更新的配置重新加载),而不必关闭VM——我已经使用了这个技巧,能够让服务器应用程序重新配置自己并重新加载,而响应Unix信号的停机时间为零。

所以,你的问题的简单答案是“当它不再被使用时”。在几乎所有的应用程序中,都有一个明确的事实。

顺便说一句,为了反驳其他响应程序中的一个,ExecutorService可以使用守护进程线程——您可以提供一个ThreadFactory,在启动线程之前根据需要配置线程。但我建议您不要使用守护进程线程,并在定义明确的点显式关闭线程池——这不是典型的做法,但这将意味着您的代码有可能被干净地关闭,并鼓励您考虑生命周期,这可能会带来更好的代码。

 类似资料:
  • 我(新手)正在测试我对Scala期货的概念以及使用它们的正确模式。 前提 Scala的期货是要异步执行的代码块。因此,主线程创建一个或多个这样的期货,安装on成功()[注意:同样适用于On完成/onFailure]回调和收益。回调在期货完成运行时执行。 据推测,这些回调生成的结果应该由主线程使用。结果存储在Try[T]容器中,带有一次写入/多次读取约束。主线程(或任何其他线程,但这不是重点)决定何

  • 请,有人,指导我如何解决这个问题。!

  • 简介 服务提供者是所有 Lumen 应用程序的启动中心。你的应用程序,以及所有 Lumen 的核心服务,都是透过服务提供者启动。 但我们所说的「启动」指的是什么?一般而言,我们指注册事物,包括注册服务容器绑定、事件监听器、过滤器,甚至路由。服务提供者是你的应用程序配置中心所在。 如果你打开包含于 Lumen 中的 bootstrap/app.php 这一文件,你会看到 $app->register

  • 我有一个,它将计算出的数据转发到: 我希望客户端/用户能够取消任务: 这不起作用,因为这将取消外部的,而不是executor服务中计划的内部未来。 是否有可能将外部未来的传播到内部未来?

  • 这种方法的Java博士说 如果需要,最多等待给定的时间完成计算,然后检索其结果(如果可用)。 参数: 超时等待的最长时间 unit超时参数的时间单位 根据我的理解,我们对强加了一个超时,我们提交给,这样,我的将在指定的时间(超时)过去后中断 但是根据下面的代码,似乎超过了超时时间(2秒),我真的很难理解这一点。谁能给我指一下正确的路吗?

  • 我正在使用Service Worker创建一个渐进式Web应用程序,我正在使用Service Worker工具箱来缓存我的内容。Service Worker代码来缓存我的内容: 代码运行正常,因为我在控制台上没有看到任何错误。但是我如何检查是否从云前或上面配置的网址的图像正在缓存和从缓存本身渲染。