提问者:小点点

异步调用API Java


我正在遍历ID列表并进行查找以获取对象。 我是多线程的新手,有没有一种不使用并行流的方法来处理这个问题?

private List<MyObject> lookupById(List<String> ids) {
  List<MyObject> myObjs = new ArrayList<>();

  for(String id : ids) {
    myObjs.add(apiService.lookUp(id));
  }

  return myObjs;
}

共2个答案

匿名用户

我是这么想的:

private List<MyObject> lookupById(List<String> ids) {

    List<MyObject> myObjs = Collections.synchronizedList(new ArrayList<>());

    AtomicInteger jobs = new AtomicInteger(ids.size());
    ids.forEach(e -> {

        new Thread(() -> {

            myObjs.add(apiService.lookUp(e));
            jobs.decrementAndGet();

        }).start();

    });

    //this can be infite loop if one of the thread get stuck at apiService.loopUp
    while(jobs.get() > 0){
        Thread.sleep(1);
    }

    return myObjs;

}

也可以有其他的方法。

匿名用户

这里有一种执行程序服务的方法。

ExecutorService pool = Executors.newFixedThreadPool(N);
List<Future<MyObject>> futures = ids.stream().map( 
                                     pool.sumbit( 
                                         id->apiService.lookUp(id) 
                                     ).collect( Collectors.toList() );
List<MyObject> myObjs = futures.stream().map( f -> { 
                                                     try { 
                                                         f.get();
                                                     } catch (Exception e){         
                                                         return null;
                                                     }
                                             ).collect( Collectors.toList());

这样可以保持列表的顺序。 否则,线程版本可能就足够了。 我不知道你为什么不直接使用并行流。