Java 在循环中启动和关闭线程好吗?

Java 在循环中启动和关闭线程好吗?,java,executorservice,Java,Executorservice,在这段代码中,我使用两个线程处理两个任务。任务完成后,Executor服务将关闭。然后继续处理下一对“sku”和“inputText”。再次创建两个线程来处理这两个任务,然后关闭。它以这种方式继续,直到处理完所有输入 这是在本地方法中使用多线程的正常方式吗?我担心在方法中频繁创建和关闭ExecutorService局部变量可能不太好 // defined as an instance variable ExecutorService executorService = Executors.

在这段代码中,我使用两个线程处理两个任务。任务完成后,Executor服务将关闭。然后继续处理下一对“sku”和“inputText”。再次创建两个线程来处理这两个任务,然后关闭。它以这种方式继续,直到处理完所有输入

这是在本地方法中使用多线程的正常方式吗?我担心在方法中频繁创建和关闭ExecutorService局部变量可能不太好

 // defined as an instance variable 
 ExecutorService executorService = Executors.newFixedThreadPool(2);


 public ExtractedInfo execute(String sku, String inputText){ 

 ExtractedInfo info = new ExtractedInfo();    

 Callable<List<Subgraph>> retrieveTask = () -> {
        return this.retrieveAllAttributesFromGraph(sku);
    };
    Callable<String> parseTask = () -> {
        return this.executeParser(sku, inputText);
    };

    Future<List<Subgraph>> retrieveService = executorService.submit(retrieveTask);
    Future<String> parseService = executorService.submit(parseTask);

    String inputLine = null;
    List<Subgraph> allAttributes = null;

    try {
        inputLine = parseService.get();
        allAttributes = retrieveService.get();
    }catch(ExecutionException ee){
        ee.printStackTrace();
    }catch (InterruptedException ie){
        ie.printStackTrace();
    }
    **executorService.shutdown();**

    info.setInputLine(inputLine);
    info.setAttributes(allAttributes);

    return info;
}
//定义为实例变量
ExecutorService ExecutorService=Executors.newFixedThreadPool(2);
公共提取信息执行(字符串sku,字符串inputText){
ExtractedInfo info=新的ExtractedInfo();
可调用检索任务=()->{
从图形(sku)中返回此.retrieveAllAttributesFromGraph;
};
可调用的parseTask=()->{
返回此.executeParser(sku,inputText);
};
Future retrieveService=executorService.submit(retrieveTask);
Future parseService=executorService.submit(parseTask);
字符串inputLine=null;
列出所有属性=null;
试一试{
inputLine=parseService.get();
allAttributes=retrieveService.get();
}捕获(被执行者){
ee.printStackTrace();
}捕获(中断异常ie){
即printStackTrace();
}
**executorService.shutdown()**
info.setInputLine(inputLine);
信息集属性(所有属性);
退货信息;
}

记住,实现任务业务逻辑的实际对象不是池线程。没有从任务(可运行或可调用)到执行它们的线程的状态溢出。因此,没有理由放弃完美的线程而去获取新的线程


应用程序关闭时是关闭线程池的好地方。Web应用程序允许您注册一个ServletContextListener,在这里您可以在ContextDestructed方法中实现这种事情

为什么不将
executorService
声明为类的属性而不是局部变量呢?@Ivan,让我想想。Thanks@Ivan,请参阅我的更新。那么我应该调用“executorService.shutdown()”方法吗?必须为每个“inputText”调用“execute()”方法。所以我想不应该在方法内部调用“shutdown”方法?如果使用Spring,可以检查
DisposableBean
接口并覆盖
destroy()
method查看JavaDoc。当您不希望服务接受更多任务时,只需调用
.shutdown()
。在大多数应用程序中,当所有工作都已排队,并且您希望应用程序在最后一个线程完成时退出。因此,在我的情况下,可能不需要调用shutdown()方法,因为我的应用程序为其他应用程序提供了调用我的服务的接口,我不控制整个应用程序的终点。这是真的吗?不关闭池是否有任何潜在危害?@user697911:不关闭threadpool会阻止jvm退出。@user697911如Nathan所述,如果不关闭池,jvm仍将运行。对于独立桌面应用程序或具有精确工作流的应用程序(如先执行A,然后执行B,然后执行C,然后关闭)来说,这可能是一个问题。但对于24×7运行的应用程序,这不是问题,因为它们通常在外部关闭(用于部署或其他工作)