简体   繁体   English

如何等待线程在Java中完成执行?

[英]How do I wait for Threads to complete execution in Java?

I have a few calculations that I'm spawning off into new threads then when all these calculations are complete I want to continue my execution. 我有一些计算要衍生到新线程中,然后在所有这些计算完成后,我要继续执行。

Here's some mock up code that is similar to what I want to achieve without all the specifics, 这是一些模拟代码,类似于我要实现的所有细节,

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 */

What's the best way for me to do this?? 对我来说最好的方法是什么?

Check out the join() method on the Thread class - http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#join%28%29 在Thread类上检查join()方法-http: //docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#join%28%29

Something like this: 像这样:

  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;
    }

And then use isAlive() and join() to wait for execution to finish 然后使用isAlive()和join()等待执行完成

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

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

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

Use the Executor framework to submit Future tasks, which will all return in the same time as the longest single task. 使用Executor框架提交Future任务,这些任务将与最长的单个任务在同一时间返回。 In its simplest form, this would work: 最简单的形式是:

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() is a blocking call, which returns as soon as the Callable returns, but returns immediately if the Callable has already finished, so you will have both result1 and result2 in the time it takes the longest one to run. Future.get()是一个阻塞调用,它在Callable返回时立即返回,但在Callable已经完成时立即返回,因此您将花费最长的时间同时运行result1result2

Remember to submit() them all before making the first call to get() . 记住在第一次调用get() 之前先全部submit() get()


Also, if you do use Threads directly, don't extend Thread (unless you're creating a new kind of Thread , which you're not): Instead, pass a Runnable to the Thread constructor and start() the Thread . 另外,如果您确实直接使用Threads ,请不要扩展Thread (除非您要创建不是的新类型的Thread ):而是将Runnable传递给Thread构造函数,然后将start()传递给Thread

You can use CountDownLatch . 您可以使用CountDownLatch Following is the sample program: 以下是示例程序:

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();
        }
    }
}

You can call join method on your thread with this call no other thread can execute until this thread completes its execution refer join method doc , I have written a sample code, in your case Thread1 can be from calculation1 and Thread2 can be in calculation2 method. 您可以使用此调用在线程上调用join方法,直到该线程完成其执行过程后,其他线程才能执行该操作,请参考join方法doc ,我编写了示例代码,您的情况下Thread1可以来自Calculation1,而Thread2可以位于Calculation2方法中。

    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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM