我如何等待Threads在Java中完成执行?

时间:2014-12-05 06:12:20

标签: java multithreading

我有一些计算,我正在产生新的线程,然后当所有这些计算完成后,我想继续执行。

这里有一些类似于我想要实现的模拟代码,没有所有细节,

public void calculation1(){
  Thread thread = new Thread(){
    public void run(){
      /* do calculation */
    };
  };
}

public void calculation2(){
  Thread thread = new Thread(){
    public void run(){
      /* do some other calculation */
    };
  };
}

calculation1();
calculation2();

/* Wait here until calculation1() and calculation2() complete */

/* Continue execution */

这对我来说最好的方法是什么?

4 个答案:

答案 0 :(得分:3)

查看Thread类的join()方法 - http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#join%28%29

这样的事情:

  public Thread calculation1(){
      Thread thread = new Thread(){
        public void run(){
          /* do calculation */
        }
      };
      thread.start();
      return thread;
    }

    public Thread calculation2(){
      Thread thread = new Thread(){
        public void run(){
          /* do some other calculation */
        };
      };

      thread.start();
      return thread;
    }

然后使用isAlive()和join()等待执行完成

    List<Thread> threads = new ArrayList<Thread>();

    threads.add(calculation1());
    threads.add(calculation2());

    for(Thread t : threads){
        if(t.isAlive()){
           t.join();
        }
    }

答案 1 :(得分:1)

使用Executor框架提交Future个任务,这些任务将与最长的单个任务同时返回。最简单的形式是:

ExecutorService executorService = Executors.newCachedThreadPool();

Future<Object> future1 = executorService.submit(new Callable<Object>() {
    public Object call() throws Exception {
        return someValue;
    }
});
Future<Object> future2 = executorService.submit(new Callable<Object>() {
    public Object call() throws Exception {
        return someOtherValue;
    }
});

Object result1 = future1.get();
Object result2 = future2.get();

Future.get()是一个阻止调用,会在Callable返回后立即返回,但如果Callable已经完成则会立即返回,因此您将同时拥有result1result2在最长时间运行的时间内。{/ p>

在第一次调用submit()之前,请记得get()他们所有


此外,如果您确实直接使用Threads,请不要展开Thread(除非您正在创建一种新的Thread,否则您不会):将Runnable传递给Thread构造函数,start()传递给Thread

答案 2 :(得分:0)

您可以使用CountDownLatch。以下是示例程序:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class MyMaster {

   public static void main(String[] args) {
       CountDownLatch waitForSlavesToComplete = new CountDownLatch(2);
       new Thread(new MySlave1(waitForSlavesToComplete)).start();
       new Thread(new MySlave2(waitForSlavesToComplete)).start();

      // Wait for all slave threads to complete
      try {
         waitForSlavesToComplete.await(900, TimeUnit.SECONDS);
      } catch(InterruptedException e) {e.printStackTrace();}

   }
}

public class MySlave1 extends Thread {

    CountDownLatch latch = null;

    public MySlave1(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        //Perform slave specific operations

        try {
            this.latch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class MySlave2 extends Thread {

    CountDownLatch latch = null;

    public MySlave2(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        //Perform slave specific operations

        try {
            this.latch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

答案 3 :(得分:0)

你可以通过这个调用在你的线程上调用join方法没有其他线程可以执行,直到这个线程完成它的执行参考join method doc,我已经编写了一个示例代码,在你的情况下,Thread1可以来自calculation1和Thread2可以在calculate2方法中。

    Thread thread1 = new Thread()
    {
      @Override
      public void run()
      {
        System.out.println("thread1 is running from method calculation1");
        try
        {
          Thread.sleep(10000);
        } catch (InterruptedException e)
        {
          e.printStackTrace();
        }
      }
    };

    thread1.start();
    try
    {
      thread1.join();
    }
    catch (InterruptedException e1)
    {
      e1.printStackTrace();
    }

    Thread thread2 = new Thread()
    {
      @Override
      public void run()
      {
        System.out.println("thread2 is running from method calculation2");
        try
        {
          Thread.sleep(1000);
        } catch (InterruptedException e)
        {
          e.printStackTrace();
        }
      }
    };
    thread2.start();
    try
    {
      thread2.join();
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
//now here if you have more threads then that will not start until thread 1 and thread 2 are completed