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; }
    //准备返回
  • 相关阅读:
    织梦DEDECMS更换目录后需要修改的内容绝对路径与相对路径问题
    <dedecms开发》给dede自定义表单添加提交验证功能
    PLSQL存储过程中的内部存储过程
    在Oracle中查询存储过程和函数
    PLSQL存储过程调用存储过程对异常的处理问题
    带参数存储过程的小例子
    对PLSQL的SQL%NOTFOUND的再验证
    PLSQL restrict reference的做法
    PLSQL的 dynamic sql小例子
    PLSQL execute immediate
  • 原文地址:https://www.cnblogs.com/libin6505/p/15317809.html
Copyright © 2011-2022 走看看