【问题标题】:Java executor service: Waiting for all tasks to finishJava 执行器服务:等待所有任务完成
【发布时间】:2021-02-08 04:59:09
【问题描述】:

我正在尝试在我的程序中引入并发性。程序结构是这样的:

    ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
    List<String> initialData = dao.fetchFromDB("input");
    Queue queue = new MyQueue();
    queue.add(initialData);

    while(queue.length() > 0) {
        int startingLength = queue.length();
        for (int i = 0; i < startingLength; i++) {
            String input = queue.remove();
            if(input.equals("some value")) {
              missionAccomplished = true;
              break;
            } else {
                  MyRunnable task = new MyRunnable(input, queue, dao);
                  executor.execute(task);
            }
            
        }
        if(missionAccomplished) {
           break;
        } 
        executor.shutdown();
    }
 

所以队列中包含了需要一一处理的数据。在while循环中,我运行一个for循环,它依次从队列中挑选数据并对其进行一些检查,如果检查失败,我将使用这些数据创建一个可运行的任务并将其交给执行程序(因为数据库操作很耗时,我想为此使用并行性)。 for 循环在给定的 while 迭代中仅选择特定长度的数据。 我想要实现的是,只有在当前迭代中提交给执行程序的所有任务都完成时,'while'循环才会进入下一次迭代。

如何做到这一点?

【问题讨论】:

    标签: java concurrency parallel-processing executorservice


    【解决方案1】:
    Project Loom 中的

    try-with-resources

    你问:

    我想要实现的是,只有在当前迭代中提交给执行器的所有任务都完成时,'while'循环才会进入下一个迭代。

    Project Loom 承诺让这一切变得更简单。

    Project Loom 带来的变化之一是ExecutorService 接口是AutoCloseable 的子接口。这意味着我们可以使用try-with-resources 语法。 try-with-resources 会自动阻止,直到所有提交的任务都完成/失败/取消 - 正是您所要求的。

    另外,执行器服务在退出try 时会自动关闭。这些更改意味着您的代码变得更简单、更清晰。

    此外,对于经常阻塞的代码,例如数据库访问,您将看到使用虚拟线程(又名fibers)显着提高性能。虚拟线程是 Project Loom 的另一个新特性。要获得此功能,请致电Executors.newVirtualThreadExecutor

    Project Loom 的实验版本是 available now,基于早期访问 Java 17。Loom 团队正在征求反馈意见。有关详细信息,请参阅 Oracle 的 Ron Pressler 最近的演讲和采访。

    System.out.println( "INFO - executor service about to start. " + Instant.now() );
    try (
            ExecutorService executorService = Executors.newVirtualThreadExecutor() ;
    )
    {
        for ( int i = 0 ; i < 7 ; i++ )
        {
            executorService.submit( ( ) -> System.out.println( Instant.now() ) );
        }
    }
    // Notice that when reaching this point we block until all submitted tasks still running are fin
    // because that is the new behavior of `ExecutorService` being `AutoCloseable`.
    System.out.println( "INFO - executor service shut down at this point. " + Instant.now() );
    

    运行时。

    INFO - executor service about to start. 2021-02-08T06:27:03.500093Z
    2021-02-08T06:27:03.554440Z
    2021-02-08T06:27:03.554517Z
    2021-02-08T06:27:03.554682Z
    2021-02-08T06:27:03.554837Z
    2021-02-08T06:27:03.555015Z
    2021-02-08T06:27:03.555073Z
    2021-02-08T06:27:03.556675Z
    INFO - executor service shut down at this point. 2021-02-08T06:27:03.560723Z
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多