能否将多API异步调用的相似线程创建逻辑封装为方法?
线程异步调用的代码封装方案
当然可以封装!利用Java的函数式接口就能把重复逻辑抽出来,只需要把每个线程里获取参数+调用API的差异化逻辑作为参数传入通用方法即可。
第一步:封装通用线程创建方法
写一个工具方法,接收一个Supplier<List<BookResponse>>(代表获取匹配结果的逻辑),以及同步用的集合和线程列表,内部完成线程创建、启动、加入列表的重复逻辑:
private void createAndStartSearchThread(Supplier<List<BookResponse>> resultSupplier, List<BookResponse> allMatches, List<Thread> threads) { Thread thread = new Thread(() -> { try { List<BookResponse> matches = resultSupplier.get(); synchronized (allMatches) { allMatches.addAll(matches); } } catch (Exception e) { throw new CustomException(e); } }); threads.add(thread); thread.start(); }
第二步:简化原有线程创建代码
原来的多线程创建逻辑可以简化为几行调用,把差异化逻辑用Lambda表达式传入即可:
List<BookResponse> allMatches = Collections.synchronizedList(new ArrayList<>()); List<Thread> threads = new ArrayList<>(); // 按书名搜索的线程 createAndStartSearchThread(() -> { String someParam = someMethod(); return fetchMethod(someParam); }, allMatches, threads); // 按内容搜索的线程 createAndStartSearchThread(() -> { int intParam = anyMethod(); return differentFetchMethod(intParam); }, allMatches, threads); // 其他搜索线程... createAndStartSearchThread(() -> { Double priceParam = priceMethod(); return priceFetchMethod(priceParam); }, allMatches, threads); // 等待所有线程完成 for (Thread thread : threads) { try { thread.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CustomException(e); } } return new ResponseEntity<>(allMatches, HttpStatus.OK);
补充优化建议
- 用线程池替代原始线程:如果线程数量较多,建议用线程池(比如
Executors.newFixedThreadPool())管理线程,避免资源过载:
ExecutorService executor = Executors.newFixedThreadPool(5); private void submitSearchTask(Supplier<List<BookResponse>> resultSupplier, List<BookResponse> allMatches, ExecutorService executor) { executor.submit(() -> { try { List<BookResponse> matches = resultSupplier.get(); synchronized (allMatches) { allMatches.addAll(matches); } } catch (Exception e) { throw new CustomException(e); } }); } // 使用后记得关闭线程池 executor.shutdown(); executor.awaitTermination(1, TimeUnit.MINUTES);
- 用线程安全集合简化同步:可以用
CopyOnWriteArrayList替代synchronizedList加同步块,省去手动加锁步骤:
List<BookResponse> allMatches = new CopyOnWriteArrayList<>(); // 直接调用addAll,无需synchronized块 allMatches.addAll(matches);
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

