线程池多线程等所有线程都执行完及callable的使用【我补充】

方法一:

作者:木女孩
链接:https://www.zhihu.com/question/52580874/answer/131132215
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

public class Test1 {

    public static ExecutorService executorService = Executors.newCachedThreadPool();
    private static CountDownLatch cdl = new CountDownLatch(10);
    private static final Random random = new Random();

    public void test() {
        for (int i = 0; i < 10; i++) executorService.execute(new ThreadTest());
    }

    public static void main(String[] args) {
        new Test1().test();

        //插入数据完成后  执行修改操作
        try {
            cdl.await();
        } catch (InterruptedException e) {
        }
        System.out.println("它们已经插完啦..............................");
        executorService.shutdown();

    }

    class ThreadTest implements Runnable {

        public void run() {
            //执行插入数据操作  每次插入一条
            // 模拟耗时
            int time = random.nextInt(10000);
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
            }
            System.out.println(Thread.currentThread().getName() + "执行完了,耗时:" + time / 1000 + "秒");
            cdl.countDown();
        }
    }
}

一种是上面的回答用CountDownLatch
另外一种思路就是用Callable:
好处就是精确知道每个线程的任务执行结果。

方法二:

作者:匿名用户
链接:https://www.zhihu.com/question/52580874/answer/131135646
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
public class JavaTest {
    public static ExecutorService executorService = Executors.newCachedThreadPool();

    public  void test(){
        Future<Boolean>[] futures=new Future[10];
        for (int i = 0 ;i<10;i++)
            futures[i]=executorService.submit(new ThreadTest());
        for (int i = 0; i < 10; i++) {
            try {
                boolean success= futures[i].get();
                System.out.println(String.format(Locale.CHINA,"执行完毕,结果为%s",success));
            } catch (InterruptedException|ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        new JavaTest().test();
        System.out.println("执行其他任务");
        executorService.shutdown();

    }

    class ThreadTest implements Callable<Boolean>{

        @Override
        public Boolean call() throws Exception {
            System.out.println("开始插入数据");
            Thread.sleep(2000);
            return true;
        }
    }
}

我的例子

  public void testDaysFor() throws Exception{
        long l1 = System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(4);
        List<TradeStatistics> list = new ArrayList<>();
        //计算总执行次数,为了创建创建Feature数组
        int count = 0;
        for (int i = 5; i < 8 ; i++) {
            for (int j = 3; j < i-2; j++) {
                count++;
            }
        }
        log.info("预计总执行次数:{}",count);
     //创建Feature数组 Future
<TradeStatistics>[] futures=new Future[count]; //重新赋值0,开多线程执行业务 count = 0; for (int i = 5; i < 8 ; i++) { for (int j = 3; j < i-2; j++) { log.info("j:{},i:{}",j,i); // Future<TradeStatistics> future = executor.submit(new TaskThread(i, j));
         //给数组赋值并开启多线程
futures[count] = executor.submit(new MyThread(i, j)); count++; } } //多线程都启动好了后,开始阻塞获取结果,转为主线程同步执行后面代码 for (int i = 0; i < count; i++) { //下面这个get方法会阻塞到每个feature对象对应的线程执行完 TradeStatistics tradeStatistics = futures[i].get(); //添加到集合 list.add(tradeStatistics); } //关闭线程池 executor.shutdown(); long l2 = System.currentTimeMillis(); log.info("一共获取到:{}个,耗时:{}秒",list.size(),(l2-l1)/1000); //打印统计信息 for (int i = 0; i < list.size(); i++) { TradeStatistics ts = list.get(i); Double successRate = ts.getSuccessRate(); Integer finalProfit = ts.getFinalProfit(); String desc = ts.getStrategy().getDesc(); Integer id = ts.getId(); Integer closeSum = ts.getCloseSum(); log.info("id:{},益:{},率:{},共:{}次,策:{}",id,finalProfit,successRate, closeSum,desc); } } //线程任务 class MyThread implements Callable<TradeStatistics>{ Integer i; Integer j; public MyThread(Integer i, Integer j){ this.i = i; this.j = j; } @Override public TradeStatistics call() throws Exception {
         //自定义的返回对象 TradeStatistics ts
= new TradeStatistics();
         //因为逻辑 ts.setIsRemind(
false); ts.setInitAccount(100000); //避免内存占用过大 ts.setAllPrices(null); return ts; } }

我的例子2:

//多线程查询32个省数据方法
    Object  test(){
        //查询32个省编码
        List<Map> provinceList = xxMapper.qryProvince();
        //总成功失败量
        Integer sumSuccess = 0;
        Integer sumFail = 0;
        //返回省份数据集合
        //开启多线程执行32个省查询
//            ExecutorService executor = Executors.newFixedThreadPool(8);
        ExecutorService executor = Executors.newCachedThreadPool();
        //线程返回对象集合
        Future<Map<String,Integer>>[] futures=new Future[provinceList.size()];
        //循环启动多线程
        for (int i = 0; i <provinceList.size(); i++) {
            Map provinceMap = provinceList.get(i);
            //启动线程
            futures[i] = executor.submit(() -> {
                //这里面其实是callable方法里面是业务逻辑
                Integer regionId = Integer.valueOf(provinceMap.get("regionId")+"");
                String regionName = String.valueOf(provinceMap.get("regionName"));
                HashMap tempMap = new HashMap<String,Integer>();
                tempMap.put("regionName",regionName);
                //成功
                Integer successCount = xxMapper.qrySuccessCount(regionId, yearMonth, xx, null);
                tempMap.put("successCount",successCount);
                //失败
                Integer failCount = xxMapper.qryFailCount(regionId,yearMonth,xx,null);
                tempMap.put("failCount",failCount);
         
//返回值就是callable线程执行的返回结果 return tempMap; }); } //多线程都启动好了后,开始阻塞获取结果,然后转为主线程同步执行后面代码 ArrayList<Map> provinceMapList = new ArrayList<>(); for (int i = 0; i < provinceList.size(); i++) { //下面这个get方法会阻塞到每个feature对象对应的线程执行完 Map<String,Integer> map = futures[i].get();
       
//组装每个线程的返回值到返回对象 sumSuccess+=map.get("successCount"); sumFail+=map.get("failCount"); //准备返回 provinceMapList.add(map); } //关闭线程池 executor.shutdown(); //封装返回 HashMap rtnMap = new HashMap(); rtnMap.put("provinceList",provinceMapList); rtnMap.put("sumSuccessCount",sumSuccess); rtnMap.put("sumFailCount",sumFail); rtnMap.put("sumCount",sumSuccess+sumFail); return rtnMap; }
//准备返回
原文地址:https://www.cnblogs.com/libin6505/p/15317809.html