使用 2 个线程的更快输出

Using the faster output from 2 threads

我想在我的 Java 程序中使用两个线程来处理一小部分。我需要第一次调用数据库,第二次调用 API,两次调用都使用相同的输入,然后使用先完成的线程的输出。

这是我第一次用线程编程,我很困惑。我看过教程,它们主要解释了如何使用线程完成两件独立的事情,所以我有点迷茫。

有人可以帮助我或将我重定向到他们可能拥有的任何有用的 link 吗?

到目前为止,据我了解,它应该看起来像这样吗? :

Thread thread1 = new Thread(func1());
Thread thread2 = new Thread(func2());
thread1.start();
thread2.start();

但是我该如何提取函数的输出呢?我怎么知道哪个先完成?

------------更新 1---------

在尝试 CompletableFuture 之后(感谢 Johan 的帮助!)我有这样的事情:

CompletableFuture<Object> getData = CompletableFuture.anyOf(
        CompletableFuture.runAsync(() -> getDataFromDB(clientData)),
        CompletableFuture.runAsync(() -> getDataFromApi(clientData))
    );

    getData.thenApply(dataObject -> {
        // Cast the returned Object to the actual type of your data,
        // assuming both getDataFromDb and getDataFromApi 
        // return the same result type
        Object data = (String) dataObject;

        // Work with the returned data.
        result = (String) data;
    });

但我收到 getData.thenApply() 的错误:

CompletableFuture 类型中的方法 thenApply(Function) 不适用于参数 (( dataObject) -> {})

既然我知道 getData in 是 String 类型,是否可以将其转换为 String 并存储结果?

您可以使用ExecutorService.invokeAny

执行给定的任务,return获取已成功完成(即未抛出异常)的任务的结果(如果有的话)。正常或异常 return 时,未完成的任务将被取消。如果在此操作过程中修改了给定的集合,则此方法的结果是未定义的。

Java 8 提供了一个非常好的 utility class called CompletableFuture,可以帮助你。

创建两个 CompletableFuture,每个任务一个,然后使用 CompletableFuture.anyOf 方法等待其中一个完成。

CompletableFuture<TData> getData = CompletableFuture.anyOf(
    CompletableFuture.runAsync(() -> getDataFromDb()),
    CompletableFuture.runAsync(() -> getDataFromApi())
);

getData.thenApply(dataObject -> {
    // Cast the returned Object to the actual type of your data,
    // assuming both getDataFromDb and getDataFromApi 
    // return the same result type
    TData data = (TData)dataObject;

    // Work with the returned data.
    processData(data);
});

正如@Johan Hirsch 建议尝试 CompletableFuture。我刚试过这个并且有效:

    CompletableFuture.anyOf(
            CompletableFuture.supplyAsync(() -> getDataFromDB(clientData)),
            CompletableFuture.supplyAsync(() -> getDataFromApi(clientData)))
            .thenApply(item -> (String) item)
            .thenAccept(result -> {
                // Consume the data
                System.out.println(result);
            });

请注意,我目前正在 使用 数据,所以它不会 return 任何东西。如果您只想将结果传递给另一个 CompletableFuture,请将 thenAccept 方法更改为 thenApply