Spider
Spider

Reputation: 455

Calling an API asynchronously java

I am looping through a list of IDs and doing a look up to get objects. I'm new to multi threading, is there a way to handle this without using parallel streams?

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

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

  return myObjs;
}

Upvotes: 0

Views: 72

Answers (2)

matt
matt

Reputation: 12337

Here's a way with an executor service.

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());

This keeps the order of the list. Otherwise the thread version might be sufficient. I don't know why you wouldn't just use a parallel stream.

The advantages this has over the accepted solution.

  • The list is in the same order.
  • If there is an exception, null gets added instead of never finishing.
  • Doesn't create an unlimited number of threads. Only creates 'N' which should be a reasonable number.

Upvotes: 1

KunLun
KunLun

Reputation: 3225

This is what I'm thinking:

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

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

    CountDownLatch countDownLatch = new CountDownLatch(ids.size());
    ids.forEach(e -> {

        new Thread(() -> {

            myObjs.add(apiService.lookUp(e));
            countDownLatch.countDown();

        }).start();

    });

    try{
        countDownLatch.await();
    }catch(Exception ignored){}

    return myObjs;

}

Also there can be other ways.

Upvotes: 2

Related Questions