簡體   English   中英

如何在Java中發送異步請求並收集響應

[英]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個線程。

我終於使用ExecutorServiceFuture解決了它

我發布了答案:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM