gpt4 book ai didi

java - 我如何用 Java 编写这个等效代码?

转载 作者:行者123 更新时间:2023-11-29 08:37:23 25 4
gpt4 key购买 nike

我有一个异步 C++ 函数需要将工作传递给另一个线程,然后等待该工作完成。我使用 std::promise 对象完成了此操作,如下所示:

void task(std::function<void()> const& func) {
std::promise<void> promise;
//You can think of 'thread_pool' as being a wrapper around a std::vector<std::thread>
//where all the threads have a body that more-or-less look like
/* void run() {
* while(running) {
* task t;
* if(task_queue.try_pop(t)) t();
* }
* }
*/
thread_pool.post([&] {
try {
func();
promise.set_value();
} catch (...) {
promise.set_exception(std::current_exception());
}
});

promise.get_future().get();
}

所以我的问题是,在 Java 中表达相同概念的最简单方法是什么?在我的具体案例中,我需要管理 Swing 线程和 JavaFX 线程之间的通信,并管理两者之间的任务。这是我目前所拥有的:

public static void runAndWait(Runnable runner) {
Future<Object> future = new FutureTask<>(new Callable<Object>() {
public Object call() {
try {
runner.run();
} catch (RuntimeException e) {
//??? How do I report the exception to the future?
}
return null;
}
});

Platform.runLater(/*How do I run the future I've just created?*/);

future.get();//I want the exception to throw here if we caught one.
}

很明显,我遗漏了一些东西。我如何用Java表达我描述的C++代码?

最佳答案

这个问题似乎类似于:

还有 runAndWait您问题中的代码看起来与 Sarcan 的答案非常相似,即:

final FutureTask query = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
return queryPassword();
}
});
Platform.runLater(query);
System.out.println(query.get());

在对其他答案的评论中,我注意到您也关注异常处理。您会注意到 FutureTask 具有 setException() 的逻辑:

Causes this future to report an ExecutionException with the given throwable as its cause, unless this future has already been set or has been cancelled. This method is invoked internally by the run() method upon failure of the computation.

当内部实现调用 setException调用,您不需要显式调用 setException .在 FutureTask 的上下文中抛出的任何未捕获的异常都将在该 FutureTask 中设置,您可以通过捕获 ExecutionException 来解释它。来自你的 future.get()称呼。

// non-JavaFX thread code...

Future<Void> future = new FutureTask<>(() -> {
// work to be done on the JavaFX thread...
return null;
}
});

// do the work on the JavaFX thread.
Platform.runLater(future);

try {
// await completion of the work on the JavaFX thread.
future.get();
} catch (InterruptedException ex) {
// restore the interrupt status (see the linked Goetz article).
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
// exception handling logic for an exception occurring
// in the body of the FutureTask here.
}

在上面的示例中,我有一个 Future<Void>因为我对传递 Future 调用的任何数据结果不感兴趣。如果我对获得结果感兴趣,那么我可以使用 Future<SomeObjectType>并且有SomeObjectType result = future.get() .在这种情况下,我喜欢使用 immutable objects尽可能多(例如 SomeObjectType ),尽管对于 future.get() 并不是绝对必要的场景,因为这本质上是按顺序访问对象,而不是跨线程并行访问。

如果您想在非 JavaFX 线程上重新抛出 JavaFX 应用程序线程上发生的异常,那么您可以这样做:

} catch (ExecutionException ex) {
throw ex.getCause();
}

以下信息适用于与 JavaFX(或一般的 Java)的不同线程交互,与问题没有直接关系,因此对于回答问题的具体细节可以忽略,它仅作为背景信息。

一些背景信息:我发现 Brian Goetz 的一篇关于在 Java 中实现任务的非常出色的文章:

相反的交互:上面给出的示例涉及从另一个线程调用 JavaFX 应用程序线程上的任务并等待它们完成。如果您遇到相反的情况,您希望在另一个线程而不是 JavaFX 线程上调用任务,那么您将使用 JavaFX Task。 .在这种情况下,您不希望 JavaFX 线程等待非 JavaFX 任务的完成,因为您永远不应该暂停或挂起 JavaFX 线程(相反,必须同时执行任务调用,链接中解释了如何执行此操作任务 Javadoc)。

相关(但不同)问题中详细介绍了后台线程和 JavaFX UI 之间的交互机制:

关于java - 我如何用 Java 编写这个等效代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42907948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com