使用 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
我想在我的 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