我们有一个服务方法 GetDataParallel( ),目前可能被许多客户端调用,我们使用 ExecutorService 调用其中的 MyCallable。但是我发现除非我调用 executorService.shutdown();应用程序永远不会退出,那么为什么应用程序不能退出,我们必须在应用程序退出之前手动关闭所有线程池线程?在服务环境中,我认为我们不需要调用 executorService.shutdown();让应用程序保持活力,对吗?
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();
}
}
最佳答案
通常您会在应用程序退出时关闭 ExecutorService - 大多数应用程序都有某种生命周期和关闭顺序。如果你希望你的应用程序在主线程完成它必须做的任何事情时退出,你想在它的工作完成时关闭它(这意味着它的工作完成有一个明确定义的点,你可以知道什么时候是)。
服务器端框架通常具有生命周期方法,您可以 Hook 这些方法以检测代码何时关闭并干净退出。或者您可以使用 VM 关闭 Hook (可能延迟关闭,直到所有当前排队的作业完成),这样无论什么代码导致程序退出,您的清理代码都会运行。
一般来说,如果框架没有提供明确定义的退出点,那么创建一个定义明确的退出点是个好主意 - 它可以让您拥有一个可以干净地卸载(并且可能使用更新的配置重新加载)的应用程序,而无需VM 必须完全关闭 - 我已经使用这个技巧让服务器应用程序重新配置自身并以零停机时间重新加载以响应 Unix 信号。
因此,您问题的简单答案是“不再使用时”。在几乎任何应用程序中,都有一个点是明确正确的。
顺便说一句,为了与其他响应者之一相矛盾,ExecutorService 可以使用守护进程线程 - 您可以提供一个 ThreadFactory 来在启动线程之前根据需要配置线程。但我鼓励您不要使用守护线程并在明确定义的点显式关闭线程池——这不是典型的做法,但这都意味着您的代码有可能被干净地关闭,并且它将鼓励您考虑生命周期,这可能会带来更好的代码。
关于java - 当executorService.shutdown();应该叫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39219510/