1.使用countDown
1 public Map<Long, User> batchQueryUserInfo(List<Long> userIds) { 2 List<List<Long>> userIdPartitions = Lists.partition(userIds, 50); 3 List<User> userList = new ArrayList<>(); 4 5 CountDownLatch latch = new CountDownLatch(userIdPartitions.size()); 6 userIdPartitions.forEach(userIdsPartition -> { 7 executorService.submit(()->{ 8 try { 9 List<User> userInfoList = userService.batchQuery(userIdsPartition.stream().map(String::valueOf).collect(Collectors.toList())); 10 userList.addAll(userInfoList); 11 } catch (Exception e) { 12 //log 13 return; 14 } finally { 15 latch.countDown(); 16 } 17 }); 18 }); 19 try { 20 latch.await(1, TimeUnit.SECONDS); 21 } catch (Exception e) { 22 //log 23 } 24 return userList.stream().collect(Collectors.toMap(user -> Long.parseLong(user.getUserId()), v->v)); 25 }
2.Future.get
future.get方法会阻塞,效率不如CountDownLatch。
1 public Map<Long, User> batchQueryUserInfo(List<Long> empIds) { 2 List<List<Long>> userIdPartitions = Lists.partition(userIds, 50); 3 List<User> userList = new ArrayList<>(); 4 5 List<Future<List<User>>> futureList = new ArrayList<>(); 6 userIdPartitions.forEach(userIdsPartition -> { 7 Future<List<User>> future = executorService.submit(() -> { 8 List<User> userInfoList = null; 9 try { 10 userInfoList = userService.batchQuery(userIdsPartition.stream().map(String::valueOf).collect(Collectors.toList())); 11 } catch (Exception e) { 12 //log 13 } 14 return userInfoList; 15 }); 16 futureList.add(future); 17 18 }); 19 long timeLimit = 1; 20 for (Future<List<User>> future : futureList) { 21 try { 22 userList.addAll(future.get(timeLimit, TimeUnit.MILLISECONDS)); 23 } catch (Exception e) { 24 //log 25 } 26 } 27 return userList.stream().collect(Collectors.toMap(user -> Long.parseLong(user.getUserId()), v->v)); 28 }