【问题标题】:ExecutorService with invokeAll() and Future in javajava中带有invokeAll()和Future的ExecutorService
【发布时间】:2016-09-17 01:28:20
【问题描述】:

手头有以下代码:

    ExecutorService executor = Executors.newFixedThreadPool(10);
    Collection collection = new ArrayList();
    for (int n=1; n<100; n++)
        collection.add(new MyThread(n));

    try {
        List<Future<Boolean>> futures = executor.invokeAll(collection);

        for(Future<Boolean> future : futures){
            future.get();
            if (future.isDone()) {
                System.out.println("true");
            }
            else
                System.out.println("false");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

如果以上是正确的?
如果所有future.isDone() 都为真,那么所有线程都已经完成了吗?
我怎样才能制作一个标志,以确保所有这些都完成?

【问题讨论】:

    标签: java


    【解决方案1】:

    作为对 vainolo 回复的评论,但我没有足够的声望点:

    isDone 也是多余的,因为invokeAll 返回isDone 为真的期货列表。 javadocs mention this.

    【讨论】:

    • 这是我认为的最佳答案。澄清一下,invokeAll 在所有任务完成之前不会返回,也就是说它是阻塞的。 (有非阻塞的重载)
    【解决方案2】:

    要检查所有内容是否正确,您可以执行以下操作:

    boolean works=true;
      for(Future<Boolean> future : futures){
            future.get();
            if (future.isDone()) {
                System.out.println("true");
            }
            else{
                System.out.println("false");works=false;
            }
        }
    if(works)System.out.println("yea it works")
    

    【讨论】:

      【解决方案3】:

      使用布尔变量是了解所有线程都已完成的最简单方法。 另一种方法可能是使用原语,例如一个整数。您可以简单地增加/减少计数器以查看是否所有线程都已完成。

      另一种方法是检查您的ExecutorService 对象上的awaitTermination() 调用的返回值。

        int counter = 0;
      
        for(Future<Boolean> future : futures)
        {
              future.get();            
              if (future.isDone())
                  System.out.println("true");
              else
              {
                  counter++;
                  System.out.println("false");
              }
         }
      
         if(counter != 0)
             System.out.println("DONE!");
      
         // Another way of checking all threads are done.
         if(executor.awaitTermination(100, TimeUnit.SECONDS))
             System.out.println("DONE!");
      

      【讨论】:

      • 有必要同时使用 .get 和 .isDone 吗?如果不是,哪个更适合我的问题?
      • @fen1ksss get 和 isDone 是不同的方法。所以问“哪个更适合我的问题?”是无稽之谈。我认为您使用这些方法的方式看起来不错。
      【解决方案4】:

      通常您将 Runnable 任务添加到线程池。将线程添加到线程池不会如您所想。

      当 future.get() 为每个任务返回时,所有任务都已完成。运行任务的线程仍将运行。

      如果您想在任务完成后停止所有线程,您可以使用executor.shutdown();executor.awaitTermination


      我会这样写

      ExecutorService executor = Executors.newFixedThreadPool(10);
      List<Future<Boolean>> futures = new ArrayList<>();
      for (int n = 0; n < 100; n++)
          futures .add(executor.submit(new MyTask(n));
      
      for(Future<Boolean> future : futures) {
          boolean result = future.get();
          // do something with the result.
      }
      

      如果您不需要结果,请输入Future&lt;Void&gt;Future&lt;?&gt; 或只是Future

      【讨论】:

      • 如果不是我想的那样,我怎么能确定所有线程都完成了?
      • 您将 tasks 添加到线程池,not 线程,因为线程池已经拥有自己的线程。如果您将 Thread 添加到线程池,它甚至不会 start() 他们,因为它需要 Runnables。
      • 所以你可以叫它MyTask,你可以等到你所有的任务都完成了。
      • 你可以使用 invokeAll() 但我更喜欢创建每一个。
      【解决方案5】:

      用 value =1 初始化变量 check 并更新 else 中的值。然后在循环执行后检查 check 的值

             if (future.isDone()) {
                   System.out.println("true");
              }
              else
                  {System.out.println("false");
                   check=0;}
      

      【讨论】:

        【解决方案6】:

        如果方法future.get返回,那么future完成的计算就完成了,所以调用isDone是多余的。是的,在所有期货都完成之后,ThreadPool 中的所有线程都应该可用。

        【讨论】:

        • 所以我可以删除这部分吗? if (future.isDone()) { System.out.println("true"); } else{ System.out.println("false"); }
        • 我想是的。 Futurejavadoc 声明 get “如有必要,等待计算完成,然后检索其结果。”。所以实际上你还需要将isDone 包装在它自己的异常处理程序中。
        【解决方案7】:

        调用此方法的Invokeall 等待完成所有获取然后CPU 执行到达for 循环以检查是否完成 或者 我们需要做..while循环来检查任务的完成情况

        【讨论】:

          猜你喜欢
          • 2015-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-17
          • 2018-09-22
          相关资源
          最近更新 更多