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

ExecutorService应该在bean的整个生命周期内都是活动的,或者应该具有狭窄的(方法)范围

吕英才
2023-03-14

我有一个方法,它必须处理数千个文档。

正常处理需要时间,因此我使用ExecutorService通过让多个线程并行工作来减少处理时间。

我必须使用这种方法来处理两个长列表。

  1. 处理执行器服务的方法1:

现在,我已经在方法中初始化了ExecutorService,并用相同的方法关闭了它。(称为两次)

因此,它会导致创建和关闭ExecutorService两次。

  private List<DocDTO> convertData(args) {
    ExecutorService service = Executors.newFixedThreadPool(threads);

    List<Future<Set<DocDTO>>> futures = new ArrayList<Future<Set<DocDTO>>>();

    for (Pro pro : pros.getPros()) {
        Callable<Set<DocDTO>> callable = new Callable<Set<DocDTO>>() {
            public Set<DocDTO> call() throws Exception {        
                for loop code
            }
        };
        futures.add(service.submit(callable));
    }

    service.shutdown();
    for (Future<Set<DocDTO>> future : futures) {
        if (future.get() != null) {
            list.addAll(future.get());
        }
    }   
}   

我在看下面的链接:

http://programtalk.com/java/executorservice-not-shutting-down/

作者已在类级别创建了ExecutorService

你能告诉我在方法级或类级创建ExecutorService是否是个好主意吗?

仅供参考,上述代码中的方法一天执行两次

共有3个答案

容磊
2023-03-14

感谢Maleen和GhostCat的宝贵意见,我放弃了使用多线程的计划,原因有两个:

>

  • 当从单线程和多线程运行时,我从相同的方法中得到不同的结果

    ExecutorService不适用于惰性关系。因此,将实体的加载从懒惰更改为急切可能会影响其他功能的性能

    相反,我优化了加载实体的方式,而不是使用多线程。以前,我在for循环中逐个加载数据库中的所有静态数据,并将其保存在EhCache中。

    更改后,我使用findall方法一次加载所有静态数据,并保存在map中,从map in for循环中访问相同的数据。它大大提高了方法的性能。再次感谢你们俩。

  • 隗锐进
    2023-03-14

    首先,我建议您阅读本文档,了解如何使用spring来启用TaskExecutor服务。正如GhostCat正确建议的,它应该在类级别。此外,我建议为它创建一个单独的bean。

    前任:

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        return executor;
    }
    

    我从这个答案中得到了答案,但你们可以在互联网上找到很多不同的配置。

    楚乐逸
    2023-03-14

    自然的选择是将此类服务作为一个类字段。

    建立这样的服务不是免费的。您花费了“构建”线程池的开销;以及正确关闭它的时间——每次调用该方法。

    很多时候,那不是你想要的。你想花一次时间(比如:当保存服务的对象被创建时)。

    一个缺点是:现在持有服务的类的“生命周期”很重要。因为您现在可能需要担心显式调用该holder类所拥有的服务。

    换句话说:当您不得不担心性能时,您可能会将服务更改为类的一个字段。

    但是:您明确声明每天调用此方法两次。那么您绝对不需要担心创建/关闭该服务所产生的开销。即使开销会导致1秒的计算时间——每天2秒也没关系。

    因此,鉴于这一要求,我(个人)的建议是:保持代码原样。除非有真正的问题需要解决,否则不要触摸正在运行的系统。

     类似资料:
    • 问题内容: 我是React.js的新手,我正在努力理解React生命周期方法中的几种方法。 到目前为止,我感到有些困惑: 1) 据我了解,之间的差别,并 是,当父改变了道具,我们可以使用的setState(这个孩子里面的setState将被调用)。 例如:react-table-sorter-demo 在TableSorter中,我们有 意味着当我们进行更改时,我们期望在TableSorter中被

    • 我在开始新活动时遇到了一些问题。在我的应用程序中,我设置了侦听意图的广播接收器(屏幕关闭)。当屏幕关闭时,我的应用程序应该开始新活动(当然在某些情况下。我没有制作垃圾邮件应用程序)。但有时不是。 我在清单中声明了活动“singleTop”,所以我也重写了“onNewIntent”方法。(我认为这很重要)但事情是这样的。 当手机进入睡眠状态并且满足某些条件时,屏幕上会出现两个图标(“我的活动”)。我

    • 问题内容: 我正在尝试将html实体转换为unichar,html实体是 当我尝试执行以下操作时: 我收到以下错误消息: 似乎超出了unichar的范围转换范围。 问题答案: 您可以使用以下编码对具有Unicode转义符(后跟8个十六进制数字,零填充)的字符串进行解码: 在狭窄的版本中,它存储为UTF-16代理对: 在编码过程中,此代理对已作为代码单元正确处理:

    • 本章第一节的内容简单讲解了应用和扩展的区别,本节将为大家讲解应用和扩展的另一大区别,生命周期。 对于扩展来说,如果定义了后台脚本,同时指定persistent属性为true,那么这个扩展只要浏览器运行就会一直运行,除非用户手动去关闭它。如果声明了background权限,则这个扩展会一开机就运行,并且一直运行下去。但是对于应用来说情况会有所不同。 Chrome应用目前不允许使用永久运行的后台脚本(

    • 我对Spring的生命周期感到困惑。 上面的代码片段是否创建了对象? 如果上述答案为真。 a) 然后,对于作用域为“singleton”的bean,获取在上述代码片段中创建的对象。我是对还是错? b)对于范围为“原型”的情况,创建的对象是否未使用。因为,容器总是返回新对象。 上面的代码片段是否创建了对象? 如果答案是假的, Spring框架如何验证bean定义是否正确。 根据亨利的回答 通常,单例

    • 最近,我开始了一个新的项目,其中具有单个抽象方法的所有接口都用来代替。我经常看到有人在界面中添加另一个抽象方法后删除注释。我什么时候问过为什么?他们告诉我,公司里有个不在的人让他们那样做。现在我不确定对显然不会与lambdas一起使用的接口进行注释是不是一个好主意。 现在我看到了一个有用的信息,就是人们甚至在服务中也在使用anotation。我就像一个代码: