zoukankan      html  css  js  c++  java
  • 线程池多线程等所有线程都执行完及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; }
    //准备返回
  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/libin6505/p/15317809.html
Copyright © 2011-2022 走看看