我想运行几个线程并在我的main方法结束时加入它们,所以我可以知道它们何时完成并处理一些信息.
我不想把我的线程放在一个数组中,并且一个接一个地执行join(),因为join是一个阻塞方法,我会在主线程中等待仍然运行的一些线程,而其他线程可能已经完成,没有可能知道.
我已经考虑过为我的线程实现一个观察者模式的可能性:一个带有update()方法的接口,一个从线程扩展的抽象类(或实现runnable),用于侦听器的set和get方法以及一个启动所有线程的类等他们完成
如果我的理解是正确的,观察者就不会阻塞特定的join()来获取一个线程.相反,它将以某种方式等待,直到线程调用update()方法来执行操作.在这种情况下,应在线程完成后立即调用update().
我对如何实现这一点毫无头绪.我尝试过类似的模型,但我不知道如何使用观察者/监听器唤醒/阻止我的主线程.我已经使用这个旧帖子作为模板:How to know if other threads have finished?但是一旦线程调用update()方法,我找不到唤醒我的main方法的方法.将只为所有线程实例化一个观察者对象.
你能想到一种方法来使用观察者模式来等待所有线程完成而不会阻塞main一个接一个的join()调用吗?任何其他建议来解决这个问题将不胜感激.提前致谢.
解决方法
我认为你不需要观察者模式.线程等待任何结果将不得不阻止,否则它将完成或循环无穷大.你可以使用某种BlockingQueue – 生成器会将计算结果添加到阻塞队列(然后完成),主线程只会在没有任何结果的情况下接收这些结果.
对你好消息,它已经实现了:) CompletionService和Executors框架的很好的机制.试试这个:
private static final int NTHREADS = 5; private static final int NTASKS = 100; private static final ExecutorService exec = Executors.newFixedThreadPool(NTHREADS); public static void main(String[] args) throws InterruptedException { final CompletionService<Long> ecs = new ExecutorCompletionService<Long>(exec); for (final int i = 0; i < NTASKS ; ++i) { Callable<Long> task = new Callable<Long>() { @Override public Long call() throws Exception { return i; } }; ecs.submit(task); } for (int i = 0; i < NTASKS; ++i) { try { long l = ecs.take().get(); System.out.print(l); } catch (ExecutionException e) { e.getCause().printStackTrace(); } } exec.shutdownNow(); exec.awaitTermination(50,TimeUnit.MILLISECONDS); }