[英]How to send requests parallel to asynchronous services and collect the responses in a Java EE application?
[英]How to send Asynchronous Requests in Java and Collect Responses
我有一個讓我們說2000用戶id的列表,我想將異步請求發送到同一個服務器,將id作為參數傳遞給WebTarget
。
系統將返回映射到UserReport類的JSON。 它包含List<User>
,大小為1(如果找到用戶)。
對於每個結果,我想將用戶保存在DataBase中。 有沒有辦法讓它全部異步? 即我得到響應后立即向數據庫發送INSERT。
我發送單個請求的代碼:
public UserReport runRequest(String id){
return this.webTarget.path("some_path")
.queryParam("id", id)
.request(MediaType.TEXT_PLAIN_TYPE)
.get(new GenericType<UserReport >() {});
}
最后一個問題..使用Observable還是Future?
首先,大小為0或1的List<User>
可以更改為Optional<User>
。
您可以使用flatMap
來調度異步任務。 這是我的代碼。
public class Q43912265 {
static Random random = new Random();
public static void main(String[] args) {
Observable.range(1, 1000)
.map(String::valueOf)
.flatMap(id ->
Observable.just(id)
.observeOn(Schedulers.io())
.map(Q43912265::runRequest))
.filter(ur -> ur.getUser().isPresent())
.doOnNext(Q43912265::insert)
.subscribe();
}
@SneakyThrows(InterruptedException.class)
static UserReport runRequest(String id) {
System.out.printf("request %s on %s\n", id, Thread.currentThread());
Thread.sleep(random.nextInt(1000));
System.out.printf("done %s on %s\n", id, Thread.currentThread());
return new UserReport(id, Optional.ofNullable(random.nextDouble() > 0.7 ? null : new User(random.nextInt())));
}
static void insert(UserReport ur) {
System.err.printf("insert %s on %s\n", ur, Thread.currentThread());
}
}
@Value
class UserReport {
String id;
Optional<User> user;
}
@Value
class User {
int id;
}
請注意,如果直接運行上面的代碼,它將在所有任務完成之前終止。 使它阻止。
在這種情況下,您可以使用有限的線程更改調度程序,或者io
調度程序將創建大約1000個線程。
我終於使用ExecutorService
和Future
解決了它
我發布了答案:
public List<User> getAllUsers(List<String> ids) {
List<Future<UserReport>> futures = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(10);
int counterU = 0;
for (String id : ids) {
Callable<UserReport> task = () -> {
return runRequest(id);
};
futures.add(executor.submit(task));
LOGGER.info("Added Task {} for UserId {}.", counterH++, id);
}
List<User> toReturn = new ArrayList<>();
for (Future<UserReport> future : futures) {
try {
UserReport report = future.get();
if (report.getUsers() != null) {
User temp = report.getUsers().get(0);
LOGGER.info("Got details for User {}.", temp.getId());
toReturn.add(temp);
insertUserToDB(temp);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
executor.shutdown();
return toReturn;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.