【问题标题】:java multithreading for synchronization between tasks用于任务之间同步的java多线程
【发布时间】:2013-11-18 07:37:37
【问题描述】:

我对java中的多线程环境有一个要求。问题是这样的;

我假设有 10 个不同的任务,我想将所有这 10 个任务分配给 10 个不同的线程。现在,这些任务的完成时间可能会有所不同。当这10个线程全部完成时,还有一些整理或清除任务应该执行。换句话说,我需要等到所有线程都完成,然后才能继续执行我的进一步代码。

如果需要更多详细信息,请告诉我。

谢谢, 阿什什

【问题讨论】:

标签: java multithreading synchronized


【解决方案1】:

听起来是CountDownLatch 的理想工作。

用 10 个计数对其进行初始化,当每个线程完成其工作时,它会倒数。 当所有 10 个线程都完成后,CountDownLatch 将让原来的线程运行,它可以执行清理。

然后启动一个带有 10 个固定线程的 ExecutorService 来运行任务。

【讨论】:

    【解决方案2】:

    CyclicBarier (JDK java.util.concurrent) 大小为 10 是您的完美解决方案。使用 CyclicBarier,您可以等待 10 个线程。如果所有线程都达到了barier,那么你可以走得更远。

    编辑:CyclicBarierCountDownLatch 几乎相同,但您可以重用 barier 调用 reset() 方法。

    【讨论】:

    • @Izmaki 您可以使用任何整数值构造 CyclicBarier
    • 我在您编辑之前发表了评论。无视评论。
    • 优点是你可以提供一个单线程的屏障动作,当所有参与者都在时执行。
    【解决方案3】:

    虽然CountDownLatchCyclicBarier 负责同步多个线程并在所有线程达到所需点时执行一个操作,但它们需要所有任务主动使用此功能。如果您只对完成整个任务感​​兴趣,则解决方案可以更简单:将所有任务添加到 Collection 并使用 ExecutorServiceinvokeAll 方法,该方法在所有任务完成后返回完全的。一个简单的例子:

    Callable<Void> simpleTask=new Callable<Void>() {
      public Void call() {
        System.out.println("Performing one job");
        return null;
      }
    };
    List<Callable<Void>> list = Collections.nCopies(10, simpleTask);
    ExecutorService es=Executors.newFixedThreadPool(10);
    es.invokeAll(list);
    System.out.println("All completed");
    

    【讨论】:

      【解决方案4】:

      如果每个线程在完成后终止,您可以使用join() 语句。 simple example 可以在基本 Java 教程中找到。

          ArrayList<Thread> myThreads = new ArrayList<Thread>();
          for (int i = 0; i < 10; i++){
              //MyTaskRunnable is a Runnable with your logic
              Thread t = new Thread(new MyTaskRunnable());
              myThreads.add(t);
          }
          for(Thread t : myThreads){
              t.start();
          }
          //here all threads are running
      
          for(Thread t : myThreads){
              t.join();
          }
          //here all threads have terminated
      

      编辑: 其他答案都有其优点并且在实践中非常有用,但是join() 是最基本的构造。 CyclicBarrierCountDownLatch 版本允许您的线程在达到同步点后继续运行,这在某些情况下可能是必要的。 ExecutorService 更适合需要在固定数量的线程(又名线程池)上执行的许多任务,为仅 10 个任务创建 ExecutorService 有点过激。

      最后,如果您刚开始学习 Java 或正在学习并发课程,您应该尝试所有变体,看看它们能做什么。连接是这些结构中最基本的,将帮助您了解正在发生的事情。它也是大多数其他语言支持的基本模型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-19
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多