首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有返回值的Java并发编程

带有返回值的Java并发编程
EN

Stack Overflow用户
提问于 2022-06-25 08:51:48
回答 2查看 56关注 0票数 1

我在Java并发编程方面遇到了问题。我正在写我的单身汉论文,我必须做几个方法,这些方法将返回给我一个字符串值。在“期货”中,TriggerMessageFututre和getMeterValuesFuture是一个运行在1-5秒之间的进程,完成后返回一个字符串值。

现在的问题是future.get()阻塞了我的主线程。我想在我的main中调用TriggerMessage和getMeterValue方法,而不阻塞我的主线程,并在它们完成后作为返回值获得它们的答案。我无法找到解决问题的方法,因为要么是没有返回值的解决方案,要么是阻止线程的解决方案。

代码语言:javascript
复制
private String TriggerMessage(String Messagetyp) throws InterruptedException, ExecutionException{
    Future<String> future = new communicator().TriggerMessageFuture(queue,centralSystem,Messagetyp);

    while(!future.isDone()) {
        System.out.println("[TriggerMessage]: Calculating... ");
        Thread.sleep(500);
    }

    String result = future.get(); //blocking
    return result;
}

private String getMeterValue(String key) throws Exception{
    Future<String> future = new communicator().getMeterValueFuture(queue,centralSystem,key);

    while(!future.isDone()) {
        System.out.println("[getMeterValue]: Calculating...");
        Thread.sleep(500);
    }

    String result = future.get(); //blocking
    return result;
}
EN

回答 2

Stack Overflow用户

发布于 2022-06-25 09:22:59

这取决于您所指的主线程是什么,以及您是否可以使用CompletableFutures而不是普通的旧Future

  1. 使用main(String[] args)线程

没有任何形式的封锁是不可能做到的。如果没有阻塞get,则必须阻塞BlockingQueue实现,否则主线程就会结束。

使用Swing事件调度线程

您需要提交一个从外部使用Future.get不可能的延续任务。因此,要么将此提交包含在为Future创建的任务中,要么切换到CompletableFuture

代码语言:javascript
复制
ExecutorService exec = ...

Future<?> future = exec.submit(() -> {
   var value = someCalculation();
   SwingUtilities.invokeLater(() -> {
       useValueOnEDT(value);
   });
});

代码语言:javascript
复制
CompletableFuture<ValueType> cf = ...

cf.whenComplete((value, error) -> {
    SwingUtilities.invokeLater(() -> {
        if (error != null) {
            handleErrorOnEdt(error);
        } else {
            useValueOnEDT(value);
        }
    });
});

  1. Android主线程

这个想法和Swing一样,但是您必须使用Handler

代码语言:javascript
复制
// given value
new Handler(Looper.getMainLooper()).post(() -> {
    useValueOnMainLooper(value);
});
票数 0
EN

Stack Overflow用户

发布于 2022-06-25 09:53:46

您可以将Future包装成如下所示的CompletableFuture

代码语言:javascript
复制
static <T> CompletableFuture<T> from(Future<T> future) {
    var delegate = new CompletableFuture<T>();

    CompletableFuture.runAsync(() -> {
        try {
            delegate.complete(future.get());
        } catch (Throwable e) {
            delegate.completeExceptionally(e);
        }
    });

    return delegate;
}

然后使用该CompletableFuture通过其各种then...when...方法异步处理完成。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72752503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档