等待其他线程的回调

问题描述 投票:0回答:2

首先,我决定让我的类阻塞(让消费者更容易使用——但对我来说可能写起来更乏味)。与让消费者定义异步回调相反。这是一个好的设计模式吗?这样,用户可以获得预期的行为,但如果他们对线程的阻塞时间不满意,则可以实现自己的多线程。

我有一个构造函数,它根据异步回调的结果在类中设置最终字段:

class Example {
    private final int x;

    Example(){
        asyncFunc(/* callback */ result -> x = result)
    }
}

这不起作用,所以我使用了原子引用,并实现了一个阻塞循环,直到返回结果,如下所示:

class Example {
    private final int x;

    Example(){
        x = waitAsyncFunc();
    }

    private int waitAsyncFunc(){
        AtomicBoolean finished = new AtomicBoolean(false);
        AtomicReference<byte[]> result = new AtomicReference<>();
        asyncFunc(result -> {
            result .set(res);
            finished.set(true);
        });
        while (!finished.get()) { /* No op */ }
        return result.get();
    }

}

这是阻止/检索结果的好方法吗?

java multithreading concurrency
2个回答
4
投票

最简单的解决方案是

class Example {
    private final int x;

    Example() {
        CompletableFuture<Integer> f = new CompletableFuture();
        asyncFunc(f::complete);
        x = f.join();
    }
}

但请考虑在构建

Example
实例之前等待异步作业完成的替代方案。


3
投票

您可以使用 CountDownLatch,而不是用循环阻塞线程。

取自文档(https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

一种同步辅助工具,允许一个或多个线程等待,直到其他线程中执行的一组操作完成。

你的代码看起来像这样:

private int waitAsyncFunc() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        AtomicReference<byte[]> result = new AtomicReference<>();
        asyncFunc(result -> {
            result.set(res);
            latch.countDown();
        });
        latch.await(); //You can even specify a timeout
        return result.get();
    }
© www.soinside.com 2019 - 2024. All rights reserved.