具有返回值的线程池配合CountDownLatch实践

工作中遇到一个需求,需要通过多线程调用其他接口,再将得到的结果进行处理后返回给上层。因此, 主线程需要等待所有子线程执行完毕在执行。
实现的方法比较多,比如主线程调用sleep()方法、Thread的join()方法、CountDownLatch、CyclicBarrier等。本文选用CountDownLatch工具类,并结合线程池进行实现实现该功能。


 

public Resp getDatasourceListByOu(String ouId) {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        String Path1 = "url1";
        String Path2 = "url2";
        String Path3 = "url3";
        String Path4 = "url4";
        List<String> urlList = new ArrayList<>();
        if (!"".equals(Path1)) {
            urlList.add(Path1);
        }
        if (!"".equals(Path2)) {
            urlList.add(Path2);
        }
        if (!"".equals(Path3)) {
            urlList.add(Path3);
        }
        if (!"".equals(Path4)) {
            urlList.add(Path4);
        }

        List<FutureTask<String>> taskList = new ArrayList<>();

        CountDownLatch latch = new CountDownLatch(urlList.size());

        for (String uri : urlList) {
            FutureTask<String> futureTask = new FutureTask<>(new GetDataSourceListTask(ouId, uri, latch));
            taskList.add(futureTask);
            executorService.submit(futureTask);
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String typeResult = "";
        List<String> resultList = new ArrayList<>();
        Resp resp = new Resp();
        for (FutureTask<String> task : taskList) {
            try {
                typeResult = task.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            resp = JSON.parseObject(typeResult, resp.class);
            List<String> typeList = resp.getData();
            for (String typeNum : typeList) {
            	resultList.add(typeNum);                    
            }
        }
        if (resp.getCode() == 200) {
            return Resp.success(resultList);
        } else {
            return Resp.error(queryDataSourceTypeResp.getCode());
        }
    }

GetDataSourceListTask代码如下:

public class GetDataSourceListTask implements Callable<String> {

    private final String ouId;
    private final String url;
    private final CountDownLatch latch;

    public GetDataSourceListTask(String ouId, String url, CountDownLatch latch) {
        this.ouId = ouId;
        this.url = url;
        this.latch = latch;
    }


    @Override
    public String call() throws Exception {
        Map<String,String> map = new HashMap<>();
        map.put("ouId",ouId);
        String s = HttpClientUtil.doGet(url, map);
        latch.countDown();
        return s;
    }
}

总结:需要在主线程中初始化一个CountDownLatch对象,设置好计数器的数值。这里的数值必须和创建的任务数相同,否则主线程将会一直等待。然后
向Task类(Callable接口的实现类)中传入定义好的CountDownLatch对象,CountDownLatch可定义为final。主线程中调用latch.await()方法,Task类中调用latch.countDown()进行计数。

原文链接:https://blog.csdn.net/xuanfengofo/article/details/107213896

猜你喜欢

转载自blog.csdn.net/qq_44691484/article/details/129269352