范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

JAVA线程池之Callable返回结果

  本文介绍如何向线程池提交任务,并获得任务的执行结果。然后模拟 线程池中的线程在执行任务的过程中抛出异常时,该如何处理。
  一,执行具体任务的线程类
  要想 获得 线程的执行结果,需实现Callable接口。FactorialCalculator 计算 number的阶乘,具体实现如下:  1 import java.util.concurrent.Callable;  2 import java.util.concurrent.TimeUnit;  3   4 /**  5  * Created by Administrator on 2017/9/26.  6  */  7 public class FactorialCalculator implements Callable {  8   9     private Integer number; 10  11     public FactorialCalculator(Integer number) { 12         this.number = number; 13     } 14     public Integer call() throws Exception { 15         int result = 1; 16  17         if (number == 0 || number == 1) { 18             result = 1; 19         }else { 20             for (int i = 2; i < number; i++) { 21                 result *= i; 22                 TimeUnit.MICROSECONDS.sleep(200); 23                 if (i == 5) { 24                     throw new IllegalArgumentException("excepion happend");//计算5以上的阶乘都会抛出异常. 根据需要注释该if语句 25                 } 26             } 27         } 28         System.out.printf("%s: %d ", Thread.currentThread().getName(), result); 29         return result; 30     } 31 }
  上面23行--25行的if语句表明:如果number大于5,那么 if(i==5)成立,会抛出异常。即模拟 执行5 以上的阶乘时,会抛出异常。
  二,提交任务的Main类
  下面来看看,怎样向线程池提交任务,并获取任务的返回结果。我们一共向线程池中提交了10个任务,因此创建了一个ArrayList保存每个任务的执行结果。
  第一行,首先创建一个线程池。第二行,创建List保存10个线程的执行结果 所要存入的地方,每个任务是计算阶乘,因此线程的返回结果是 Integer。而这个结果只要计算出来了,是放在Future里面。
  第5-7行,随机生成一个10以内的整数,然后创建一个 FactorialCalculator对象,该对象就是待执行的任务,然后在第8行 通过线程池的submit方法提交。  1         ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();  2         List> resultList = new ArrayList>();  3         Random random = new Random();  4         for (int i = 0; i < 10; i ++) {  5             int rand = random.nextInt(10);  6   7             FactorialCalculator factorialCalculator = new FactorialCalculator(rand);  8             Future res = executor.submit(factorialCalculator);//异步提交, non blocking.  9             resultList.add(res); 10         }
  需要注意的是: submit方法是个非阻塞方法 ,参考这篇文章。提交了任务后,由线程池里面的线程负责执行该任务,执行完成后得到的结果最终会保存在 Future里面 ,正如第8行所示。As soon as we invoke the submit() method of ExecutorService the Callable are handed over to ExecutorService to execute.  Here one thing we have to note, the submit() is not blocking.  So, all of our Callables will be submitted right away to the ExecutorService, and ExecutorService will decide when to execute which callable.  For each Callable we get a Future object to get the result later.
  接下来,我们在do循环中,检查任务的状态---是否执行完成。  1         do {  2 //            System.out.printf("number of completed tasks: %d ", executor.getCompletedTaskCount());  3             for (int i = 0; i < resultList.size(); i++) {  4                 Future result = resultList.get(i);  5                 System.out.printf("Task %d : %s  ", i, result.isDone());  6             }  7             try {  8                 TimeUnit.MILLISECONDS.sleep(50);  9  10             } catch (InterruptedException e) { 11                 e.printStackTrace(); 12             } 13         } while (executor.getCompletedTaskCount() < resultList.size());
  第3-6行for循环,从ArrayList中取出 每个 Future,查看它的状态 isDone() ,即:是否执行完毕。
  第13行,while结束条件:当所有的线程的执行完毕时,就退出do循环。注意:当线程在执行过程中抛出异常了,也表示线程执行完毕。
  获取线程的执行结果  1         System.out.println("Results as folloers:");  2         for (int i = 0; i < resultList.size(); i++) {  3             Future result = resultList.get(i);  4             Integer number = null;  5   6             try {  7                 number = result.get();// blocking method  8             } catch (InterruptedException e) {  9                 e.printStackTrace(); 10             } catch (ExecutionException e) { 11                 e.printStackTrace(); 12             } 13             System.out.printf("task: %d, result %d: ", i, number); 14         }
  第3行取出每个存储结果的地方:Future,第7行 从Future中获得任务的执行结果。 Future.get方法是一个阻塞方法 。但前面的do-while循环里面,我们已经检查了任务的执行状态是否完成,因此这里能够很快地取出任务的执行结果。We are invoking the get() method of Future to get the result. Here we have to remember that, the get() is a blocking method.
  任务在执行过程中,若抛出异常,下面语句在获取执行结果时会直接跳到catch(ExecutionException e)中。 number = result.get()
  但它不影响Main类线程---主线程的执行。
  整个Main类代码如下: import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.*;  /**  * Created by Administrator on 2017/9/26.  */ public class Main {      public static void main(String[] args) {         ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();         List> resultList = new ArrayList>();         Random random = new Random();         for (int i = 0; i < 10; i ++) {             int rand = random.nextInt(10);              FactorialCalculator factorialCalculator = new FactorialCalculator(rand);             Future res = executor.submit(factorialCalculator);//异步提交, non blocking.             resultList.add(res);         }          // in loop check out the result is finished         do { //            System.out.printf("number of completed tasks: %d ", executor.getCompletedTaskCount());             for (int i = 0; i < resultList.size(); i++) {                 Future result = resultList.get(i);                 System.out.printf("Task %d : %s  ", i, result.isDone());             }             try {                 TimeUnit.MILLISECONDS.sleep(50);              } catch (InterruptedException e) {                 e.printStackTrace();             }         } while (executor.getCompletedTaskCount() < resultList.size());           System.out.println("Results as folloers:");         for (int i = 0; i < resultList.size(); i++) {             Future result = resultList.get(i);             Integer number = null;              try {                 number = result.get();// blocking method             } catch (InterruptedException e) {                 e.printStackTrace();             } catch (ExecutionException e) {                 e.printStackTrace();             }             System.out.printf("task: %d, result %d: ", i, number);         }         executor.shutdown();     } }
  在上面 number = result.get(); 语句中,我们 catch了两个异常,一个是InterruptedException,另一个是ExecutionException。因为我们是在main线程内获得任务的执行结果,main线程执行 result.get()会阻塞,如果在阻塞的过程中被(其他线程)中断,则抛出InterruptedException。
  若在任务的执行过程中抛出了异常(比如IllegalArgumentException),那么main线程在这里就会catch到ExecutionException。此时,就可以对抛出异常的任务"进行处理"。此外,线程池中执行该任务的线程,并不会因为 该任务在执行过程中抛出了异常而受到影响,该线程 可以继续 接收并运行 下一次提交给它的任务。
  图中 task1、task2、task4 返回的结果为空,表明它们抛出了IllegalArgumentException异常。
  最后给大家分享Spring系列的学习笔记和面试题,包含spring面试题、spring cloud面试题、spring boot面试题、spring教程笔记、spring boot教程笔记、最新阿里巴巴开发手册(63页PDF总结)、2022年Java面试手册。一共整理了1184页PDF文档。私信博主(777)领取,祝大家更上一层楼!!!
  原文作者:大熊猫同学
  原文出处:http://www.cnblogs.com/hapjin/p/7599189.html

家里来客人了做什么菜最好?你可以做这些菜,保证客人赞不绝口大家好,欢迎大家来到我的美食自媒体,我是美食领域创作者锦绣V山东专注美食,让生活更有味。今天为大家带来了几道家常美食的做法,这几道美食也是深受大家的喜欢,而且是很常见的几道美食。天养生食疗4个腊八粥食谱刮油养胃润肺腊八节,俗称腊八,即农历十二月初八,腊八这一天有吃腊八粥的习俗,腊八粥也叫七宝五味粥。冬日生活打卡季中国各地腊八粥的花样,争奇竞巧,品种繁多。最早的腊八粥是红小豆来煮,后经演变逐渐预制菜大王王栏树我相信预制菜前景广阔丨我信王栏树(农健图)人人轻松成大厨八分钟一道菜居家必囤,加热即食疫情期间,随手在网络搜索预制菜方便菜快手菜等词,都会弹出大量菜品信息梅菜扣肉孜然牙签羊肉酸菜鱼鱼香肉丝一张张诱人的图片,寒假来临,家长们如何增强孩子们的身体健康流行性感冒是由流感病毒引起的急性呼吸道传染病,尚无特效抗病毒药物。早期发现及早用药可取得较好疗效。那如何预防呢?1。户外活动时间不能少大量事实表明,坚持参加户外活动的儿童患感冒的机维生素B6几块钱一百片,却能调理改善4类健康问题,请为家人转存在维生素B大家族中,维生素B6是一个非常重要的成员。它是一种水溶性维生素,天然存在于多种食物中。小小的维生素B6虽然不起眼,但在人体内却有着重要的生理功能,作为一种重要的辅酶类物质小炒家常菜谱,美味营养健康菜值得收藏!一私房宫保鸡丁1鸡肉切丁,用蛋清料酒搅拌均匀腌制2黄瓜胡萝卜葱切块,酱油蒜瓣糖醋调成汁3锅中放油,把鸡丁炒成七分熟,装盘待用4锅中放油,放入调好的调料汁翻炒5放入豆瓣酱炒红,加入胡明日元旦,无论贫富,这6种美食要记得吃,寓意吉祥,健康迎新年在我国,元旦又被称作阳历年,元有初始之意,元旦的到来标志新一个公历年的开始,元旦佳节,不少朋友都会选择和家人亲朋相聚一堂,摆一桌丰盛的家宴,品美食,话家常,共同祝愿新的一年万事顺意核桃是血管清道夫?研究发现核桃让血管更健康,如何吃才好导语我们大家经常说人与血管同寿,所以对于每一个人而言,保持血管通畅,可以很好的促进身体健康。但是每一个人的身体当中又分布着许多血管,耳洞能够帮助输送血液,也能够达到输送营养物质的效家里暖气断了,重新打开了家里的海尔健康空调这么冷的天,不知道是管道还是什么别的原因,家里的暖气居然停了。幸亏我坚持买了冷暖两用健康空调,现在才不会挨冻。我家住高层,冬凉夏暖,夏天风进不来,室内开着风扇也完全感觉不到凉快,因元旦假期豫园灯会凭票入园,市民游客观景赏灯做好防护元旦假期,逛逛豫园灯会是一些市民的选择。正值元旦假期,豫园凭票入园,市民游客相对减少,一些市民游客做好防护,观景赏灯。今天上午记者在豫园商城多个进出门看到,管理方实行了进出分流,广李亚鹏女儿李嫣晒自拍跨年,长发披肩女神范十足,未露正脸不自信12月31日,是2022年的最后一天,已经回国的李嫣在社交平台更新动态。她没有配文,仅是晒出一张露出半张脸的照片。照片中的李嫣站在某处已经结冰的湖边,镜头对准了即将落山的太阳,夕阳
iPhone15Pro爆料压感震动替代物理按键在iPhone7系列上,苹果将Home键设计为不可按压设计,识别到手指用力按压后,会通过震动反馈来模拟机械按压的感觉,根据爆料,iPhone15Pro将针对音量键电源键也采用同样设前三季度我国工业企业效益延续恢复态势新变化透露何种新趋势?国家统计局数据显示,19月,全国规模以上工业企业营业收入同比增长8。2,两类行业利润实现了今年的首次由降转增。前三季度我国工业企业效益延续恢复态势19月份,全国规模以上工业企业实现日产汽车探讨向雷诺EV新公司出资15据共同社报道,日产汽车正探讨向法国汽车巨头雷诺力争成立的纯电动汽车(EV)新公司最多出资15。报道称,日产和三菱雷诺三家公司的企业联盟当天在线召开了会议,据分析,可能围绕向新公司出锂矿价格大涨480,新能源汽车怎么玩?特斯拉全系降价自2021年价格疯涨以来,锂矿便被大家调侃为疯狂的石头,最近它又作妖了!10月24日,澳大利亚锂矿巨头Pilbara矿业发布公告称公司已完成新一批5000吨锂精矿的出售,成交价为7vivoX90新机疑似入网,支持120W快充,或配备1英寸主摄前不久,vivo召开了一场影像战略发布会,介绍了新一代自研影像芯片以及创新的影像技术,同时也为vivoX90系列开始预热,宣布下一代影像旗舰产品将搭载更大的传感器,并且将于蔡司联合放纵的思绪记得之前同事说过,大都市的生活往往是午夜过后才刚刚开始,此时刚好是凌晨12点整,这边的城市却己开始沉寂。甄点小酒,调节那略带忧感的心情,放着丝丝轻音乐,一首又一首的歌曲,才发现越听光雾山红叶已达颜值巅峰,要来的赶紧,要不然等下一年景区介绍光雾山景区一共有四个,分别为小巫峡(看溶洞)大坝景区(看红叶以以及日出云雾)十八月潭(看红叶和十八个潭)桃园景区(看三生三世,不过十一月份不是看桃花的季节)。推荐的是大坝景iPhone15系列再次被确认充电口配置运存基本都清晰了时代一直都在快速的发展,对于手机厂商来说不能做到一直都没有特别大的改变,如果一直都没有改变的话,那么消费者可能很难进行持续的进行买账。所以现在的市场竞争非常的残酷,各大厂商都在开发iPhone14Pro难阻苹果下落iPhone新机又一次立功,扭转了苹果正在下滑的净利润。北京时间10月28日凌晨,苹果公司发布2022财年第四财季(即2022年度第三季度)财报。当季财报显示,苹果第三季度总营收9黄斌汉新能源大风口!欧盟从2035年起禁产燃油车欧盟达成历史性协议,将从2035年起禁止生产新的燃油车。此举旨在加快电气化转型,并应对气候变化。欧盟委员会欧洲议会以及欧盟成员国的谈判代表一致同意,汽车制造商必须在2035年之前实欧洲央行决定加息75个基点新华社法兰克福10月27日电(记者何丽丽)欧洲中央银行27日召开货币政策会议,决定将欧元区三大关键利率均上调75个基点。这是欧洲央行今年第三次加息。按照欧洲央行当天公布的货币政策决