带螺纹的观察者模式

Ale*_*lex 7 java multithreading design-patterns observer-pattern

我想运行几个线程并在我的main方法结束时加入它们,所以我可以知道它们何时完成并处理一些信息.

我不希望将我的线程放在一个数组中并逐个执行join(),因为join是一个阻塞方法,我会在主线程中等待一些仍在运行的线程,而其他线程可能已经完成,没有可能知道.

我已经考虑过为我的线程实现一个观察者模式的可能性:一个带有update()方法的接口,一个从线程扩展的抽象类(或实现runnable),用于监听器的set和get方法以及一个启动所有线程的类等他们完成

如果我的理解是正确的,观察者就不会阻塞特定的join()来获取一个线程.相反,它将以某种方式等待,直到线程调用update()方法来执行操作.在这种情况下,应在线程完成后立即调用update().

我对如何实现这一点毫无头绪.我尝试过类似的模型,但我不知道如何使用观察者/监听器唤醒/阻止我的主线程.我用这个旧帖子作为模板:如何知道其他线程是否已完成?但是一旦线程调用update()方法,我找不到唤醒main方法的方法.将只为所有线程实例化一个观察者对象.

你能想到一种方法来使用观察者模式来等待所有线程完成而不会阻塞main一个接一个的join()调用吗?任何其他解决这个问题的建议将不胜感激.提前致谢.

JB *_*zet 6

Java的已经有一个API来做到这一点:一CompletionService.

一种服务,它将新异步任务的生成与已完成任务的结果消耗分离.生产者提交执行任务.消费者完成任务并按照他们完成的顺序处理结果.


Mac*_*ski 5

我认为你不需要观察者模式.线程等待任何结果将不得不阻止,否则它将完成或循环无穷大.您可以使用某种BlockingQueue - 生产者将计算结果添加到阻塞队列(然后完成),主线程将在没有任何结果时接收这些结果阻塞.

对你来说是个好消息,它已经实施了:)很棒的机制CompletionServiceExecutors framework.试试这个:

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);
}
Run Code Online (Sandbox Code Playgroud)