Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带线程的观察者模式_Java_Multithreading_Design Patterns_Observer Pattern - Fatal编程技术网

Java 带线程的观察者模式

Java 带线程的观察者模式,java,multithreading,design-patterns,observer-pattern,Java,Multithreading,Design Patterns,Observer Pattern,我想运行几个线程,并在主方法的末尾加入它们,这样我就可以知道它们何时完成并处理一些信息 我不想把我的线程放在一个数组中,一个接一个地执行join(),因为join是一种阻塞方法,我会在主线程中等待一些线程仍在运行,而其他线程可能已经完成,而不可能知道 我曾考虑过为我的线程实现一个观察者模式的可能性:一个带有update()方法的接口,一个从线程扩展而来的抽象类(或实现runnable),为监听器实现set和get方法,以及一个启动所有线程并等待它们完成的类 如果我的理解是正确的,那么观察者不会阻

我想运行几个线程,并在主方法的末尾加入它们,这样我就可以知道它们何时完成并处理一些信息

我不想把我的线程放在一个数组中,一个接一个地执行join(),因为join是一种阻塞方法,我会在主线程中等待一些线程仍在运行,而其他线程可能已经完成,而不可能知道

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

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

我对如何实现这一点一无所知。我尝试过类似的模型,但我不知道如何使用observer/listener唤醒/阻止我的主线程。我将这篇旧文章用作模板:但一旦线程调用update()方法,我就找不到唤醒主方法的方法。所有线程将只实例化一个观察者对象


您能想出一种方法,使用观察者模式等待所有线程完成,而不通过逐个join()调用阻塞main吗?如有任何其他解决此问题的建议,将不胜感激。提前感谢。

Java已经有了一个API来实现这一点:a

将新异步任务的生成与已完成任务的结果的使用分离的服务。生产者提交任务以供执行。消费者接受已完成的任务,并按完成的顺序处理结果


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

好消息是,它已经实现:)伟大的
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);
}
private static final int NTHREADS=5;
专用静态最终int NTASKS=100;
private static final ExecutorService exec=Executors.newFixedThreadPool(NTHREADS);
公共静态void main(字符串[]args)引发InterruptedException{
final CompletionService ecs=新的ExecutionCompletionService(exec);
对于(最终整数i=0;i
听起来你在寻找像最近讨论的那样的东西。

哇!很高兴知道。我看到C++ism有一点小小的变化,这让我很容易被回调。我是说。无论什么我认为Java不需要“指向泛型函数的指针”语法,但我会等待发行版形成更好的意见。