当前位置: 首页 > 知识库问答 >
问题:

等待来自其他线程的回调

严心水
2023-03-14

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

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

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();
    }

}

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

共有2个答案

涂飞航
2023-03-14

可以使用倒计时锁存器,而不是用循环阻塞线程。

从文件上看(https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)

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

你的代码看起来像

private int waitAsyncFunc() throws InterruptedException {
        CountDownLatch latch = new 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();
    }
叶越
2023-03-14

最简单的解决办法是

class Example {
    private final int x;

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

但是考虑在构建示例实例之前等待异步作业完成的替代方案。

 类似资料:
  • Java 8的promise实现,即CompletableFuture,提供了应用(…)和get()方法。 其中,在必要时等待promise完成,然后返回其结果。 现在假设我们使用(或)链接一些代码以在UI线程上运行(请参见stackoverflow.com/thenApply和thenApplyAsync之间的差异)。 如果我们在UI线程中调用,比如Java以某种方式处理这种情况,或者它会导致所

  • 我们在应用程序中使用了Stomp、SpringBoot和WebSockets。服务器应用程序执行以下操作:1)生成要推送给用户的消息;2)接受WebSocket连接;3)将消息推送给ActiveMQ stomp Broker。线程转储显示了大量与simpMessagingTemplate convertAndSendToUser API调用相关联的等待线程。 应用程序的两个实例在云中运行。该应用程

  • 问题内容: 我正在为我的ubuntu服务器(针对我的多客户端匿名聊天程序)实现一种简单的线程池机制,并且需要使我的工作线程进入睡眠状态,直到需要执行一项工作(以函数指针和参数的形式) 。 我当前的系统即将关闭。我(工人线程正在)问经理是否有工作可用,以及是否有5毫秒没有睡眠。如果存在,请将作业添加到工作队列中并运行该函数。糟糕的循环浪费。 什么我 喜欢 做的是做一个简单的事件性的系统。我正在考虑有

  • 问题内容: 我有一个线程类“ MyThread”和主应用程序,简称为“ Gui”。我想从线程类创建一些对象,但在本示例中,我仅创建了一个对象。线程类完成一些工作,然后向Gui类发出信号,指示需要用户输入(此指示目前仅是更改按钮的文本)。然后,线程应等待用户输入(在这种情况下为单击按钮),然后继续执行其操作… 如何在(多个)线程中等待用户输入? 问题答案: 默认情况下,具有事件循环,可以处理信号和插

  • 问题内容: 在Linux中,可以使用backtrace()库调用来获取回溯,但是它仅返回当前线程的回溯。假设我知道它是TID(或pthread_t)并且可以保证它可以入睡,是否有任何方法可以获取其他线程的回溯? 看来libunwind(http://www.nongnu.org/libunwind/)项目可以提供帮助。问题是CentOS不支持它,因此我不希望使用它。 还有其他想法吗?谢谢。 问题答

  • 线程可以等待,直到其他线程释放访问同步块的锁。我想知道当其他线程访问同步块时,一个线程可以等待多长时间?什么时候它会知道另一个线程释放了锁?