在我的计划执行过程中,多个线程启动。 线程的量取决于用户定义的设置,但它们都执行与不同的变量的方法相同。
在某些情况下,清理需要执行中期,这部分停止所有的线程,我不希望他们停止,虽然马上,我只是设置一个变量,他们检查终止他们。 问题是,它可以达到1/2秒线程停止之前。 不过,我需要确保清理可以继续之前的所有线程都停止。 所以在技术上,我需要这个线程等待另一个线程完成清理工作是从另一个线程中执行。
我已经想到了这样做的几种方法,但他们似乎都过于复杂。 我希望会有一些方法,可以等待一组线程来完成的。 请问像这样的东西存在吗?
谢谢。
刚刚加入逐一:
for (Thread thread : threads) {
thread.join();
}
(你需要做一些与InterruptedException
,你可能想提供一个超时的情况下,不如意的事情,但是这是基本的想法...)
如果您使用的是Java 1.5或更高版本,你可以尝试的CyclicBarrier 。 您可以通过清理行动作为其构造函数的参数,并调用barrier.await()
上的所有线程时,有一个需要清理。
定义一个实用方法(或方法)自己:
public static waitFor(Collection<? extends Thread) c) throws InterruptedException {
for(Thread t : c) t.join();
}
或者你可能有一个数组
public static waitFor(Thread[] ts) throws InterruptedException {
waitFor(Arrays.asList(ts));
}
另外,您可以看看使用CyclicBarrier
在java.util.concurrent
库来实现多线程之间的任意集合点。
你见过Executor
在类java.util.concurrent
? 你可以通过一个运行的线程ExecutorService
。 它为您提供了一个对象,你可以用它来取消线程或者等待它们完成。
如果控制线程的创建(提交给ExecutorService的),那么看来你可以使用ExecutorCompletionService
看到ExecutorCompletionService? 为什么需要一个,如果我们的invokeAll有? 各种答案在那里。
如果你不控制线程的创建,这里是让你“由一个为他们完成一个”加入会话(和知道哪一个完成第一等)的方法,由红宝石启发ThreadWait类。 基本上由newing了“看线程”的警报时,其他线程终止,你可以知道什么时候“下一个”线程了许多终止的。
你会使用它是这样的:
JoinThreads join = new JoinThreads(threads);
for(int i = 0; i < threads.size(); i++) {
Thread justJoined = join.joinNextThread();
System.out.println("Done with a thread, just joined=" + justJoined);
}
和源:
public static class JoinThreads {
java.util.concurrent.LinkedBlockingQueue<Thread> doneThreads =
new LinkedBlockingQueue<Thread>();
public JoinThreads(List<Thread> threads) {
for(Thread t : threads) {
final Thread joinThis = t;
new Thread(new Runnable() {
@Override
public void run() {
try {
joinThis.join();
doneThreads.add(joinThis);
}
catch (InterruptedException e) {
// "should" never get here, since we control this thread and don't call interrupt on it
}
}
}).start();
}
}
Thread joinNextThread() throws InterruptedException {
return doneThreads.take();
}
}
这样做的好的部分是它的工作原理与普通的Java线程,不加修饰,任何线程都可以加入。 需要说明的是它需要一些额外的线程创建。 另外这个特定的实现“留下线索”如果你不叫joinNextThread()充分的次数,并没有一个“亲密”的方法,等评论在这里,如果你想创建一个更完美的版本。 你也可以使用相同类型的模式与“期货”,而不是Thread对象,等等。