使用线程池优化多任务 ThreadPoolExecutor

看优化最终效果:

System.out.println("耗时:" + (end - start)); 
// 毫秒 耗时1:28057  耗时2:27347  仅对获取用户信息方法优化后-总耗时:14288

setCorePoolSize:设置核心池大小
setMaximumPoolSize:设置线程池最大能创建的线程数目大小
keepAliveTime是线程池中空闲线程等待工作的超时时间

注意:setMaximumPoolSize之所以设置Integer.MAX_VALUE,是因为for数目太多了,设置小了等待的线程太多会不再给排队等待线程,进行抛弃提示错误。所以这里作为我的测试方法,直接取这个很大值Integer.MAX_VALUE(2147483647),正式使用建议不要这样,使用合理的最大创建线程数目大小。

仅测试练习使用,正式使用需要专研一下线程池的原理


......

public static boolean getData(Long id) throws ApiException, IOException {
       ThreadPoolExecutor executor = new ThreadPoolExecutor(5, Integer.MAX_VALUE, 2, TimeUnit.MINUTES,
               new ArrayBlockingQueue<Runnable>(5));

       getDep(id);  // 获取部门
       for (Long setId : depSet) {  // 将for循环的内容丢进线程池,每个部门id对应一个等待的获取线程
           if (!executor.isShutdown()) {  // 关闭了吗
               GetDetail get = new GetDetail(setId); // new出新的使用构造方法赋值
               executor.execute(get); // 执行
               System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
                       executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
           }
       }
       executor.shutdown(); // 关闭,但并不是真正的关闭,不再接受新任务并创建等待的线程,已进入线程池的继续执行
       System.out.println("【用户userIdSet】长度:" + userIdSet.size());
       while (true) {
           if (executor.isTerminated()) { // 判断线程池的最后一条线程终止了吗,代表真正的结束
               return true;
           }
       }

   }


   static class GetDetail implements Runnable {

       private long setId;

       public getDetail(Long setId){  // 初始的构造方法
           this.setId = setId;
       }

       @SneakyThrows
       @Override
       public void run() {
           JSONObject jsonObject = getUser(setId);
           // 钉钉报错调用当前接口次数过多,请求被暂时禁用
           // 所以这里判断是否禁用了,再重新获取一次
           if (jsonObject.getInteger("errcode") == 88) { 
               Thread.currentThread().sleep(1000);
               jsonObject = getUser(setId);
           }
           if (jsonObject.getInteger("errcode") == 0) {
               JSONObject result = jsonObject.getJSONObject("result");
               JSONArray jsonArray = result.getJSONArray("list");
               for (Object json : jsonArray) {
                   JSONObject jo = (JSONObject) json;
                   String name = jo.getString("name");
                   ......
                   ......
               }
           }
       }
   }

posted @ 2021-10-21 14:06  sailorj  阅读(196)  评论(0)    收藏  举报