执行程序中的 Thread.join() 等效项[重复]
Posted
技术标签:
【中文标题】执行程序中的 Thread.join() 等效项[重复]【英文标题】:Thread.join() equivalent in executor [duplicate] 【发布时间】:2013-12-28 00:36:59 【问题描述】:我有一个新手问题。我有这个代码:
public class Main
public static void main(String[] args) throws InterruptedException
// TODO Auto-generated method stub
IntHolder aHolder=new IntHolder();
aHolder.Number=0;
IncrementorThread A= new IncrementorThread(1, aHolder);
IncrementorThread B= new IncrementorThread(2, aHolder);
IncrementorThread C= new IncrementorThread(3, aHolder);
A.start();
B.start();
C.start();
A.join();
B.join();
C.join();
System.out.println("All threads completed...");
这将等待所有线程完成。如果我像这样使用Executors
:
public class Main
public static void main(String[] args)
// TODO Auto-generated method stub
IntHolder aHolder=new IntHolder();
aHolder.number=0;
IncrementalRunable A= new IncrementalRunable(1, aHolder);
IncrementalRunable B= new IncrementalRunable(2, aHolder);
IncrementalRunable C= new IncrementalRunable(3, aHolder);
ExecutorService exec = Executors.newFixedThreadPool(3);
exec.execute(A);
exec.execute(B);
exec.execute(C);
//Don't know what to do here
System.out.println("All threads completed...");
如何暂停主线程以等待执行器中的所有线程完成,即所有线程完成工作后应打印“所有线程完成...”?
【问题讨论】:
检查这个:***.com/questions/3269445/… Future 有一个阻塞的get方法 【参考方案1】:我们可以使用下面的代码来加入线程。
executor.execute(new YouThread());
try
executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS))
System.out.println("Not yet. Still waiting for termination");
catch(InterruptedException e)
e.printStackTrace();
【讨论】:
【参考方案2】:尝试以这种方式使用线程池。
executor.shutdown();
executor.awaitTermination(MAX_PRIORITY, TimeUnit.HOURS);
【讨论】:
【参考方案3】:executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS))
System.out.println("Not yet. Still waiting for termination");
使用shutdown() + awaitTermination()
组合。
编辑:
基于@Lital 的评论
List<Callable<Object>> calls = new ArrayList<Callable<Object>>();
calls.add(Executors.callable(new IncrementalRunable(1, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(2, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(3, aHolder)));
List<Future<Object>> futures = executor.invokeAll(calls);
注意:
invokeAll()
在所有任务完成之前不会返回(通过失败或完成成功执行)。
【讨论】:
你不认为仅仅为了简单的连接而关闭线程池不是一个好习惯吗? @Lital 我添加了另一种可以遵循的漂亮方法。 @NarendraPathai,太好了,这更好,但将数字更改为 1,2,3(这些是我用来打印消息的线程号) 顺便说一句:没有需要等待终止,除非你需要对它做出反应。因此,如果您之后所做的只是结束程序,那么一个简单的shutdown()
调用就足够了,如果您知道线程将正确终止。否则需要一个强有力的shutdownNow()
作为对shutdown()
的反应。
@Mariostoilov 完成,一个错字:)【参考方案4】:
如果你想等待任务完成,你不应该像这样使用执行器。 如果你不想/不能关闭你的线程池执行器怎么办? 这是更推荐的方式:
ExecutorService exec = Executors.newFixedThreadPool(3);
Collection<Future<?>> tasks = new LinkedList<Future<?>>();
Future<T> future = exec.submit(A);
tasks.add(future);
future = exec.submit(B);
tasks.add(future);
future = exec.submit(C);
tasks.add(future);
// wait for tasks completion
for (Future<?> currTask : tasks)
try
currTask.get();
catch (Throwable thrown)
Logger.error(thrown, "Error while waiting for thread completion");
【讨论】:
我同意我不应该使用这样的执行器,但我现在只是在玩 java,我很好奇如何实现这一点【参考方案5】: exec.shutdown();
// Wait until all threads are finish
exec.awaitTermination();
【讨论】:
以上是关于执行程序中的 Thread.join() 等效项[重复]的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 中的 viewWillAppear() 或其他等效项