线程池多线程等所有线程都执行完及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; }
//准备返回