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

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

鸿利智汇扣非净利同比增长576。96MiniLED项目逐渐进入放量阶段8月26日晚,鸿利智汇(300219。SZ)发布2021年半年度报告。报告显示,2021年上半年,鸿利智汇实现营业收入20。04亿元,同比增长50。65实现归属于上市公司股东的净利长盈精密新能源业务营收同比增长超200成为公司最重要增长点8月27日晚,长盈精密(300115。SZ)发布2021年上半年度财务报告。报告显示,上半年长盈精密实现营业收入45。22亿元,同比增长12。87归属于上市公司股东的净利润2。36大富科技深挖消费电子及汽车领域,相关业务保持增长8月27日,大富科技(300134。SZ)披露2021年半年度业绩报告,公司上半年实现营业收入10。52亿元。报告期内,大富科技持续发力消费电子及汽车领域,智能终端及汽车零部件业务宝馨科技收购四川富骅新能源科技26股权切入正极材料领域9月6日晚间,宝馨科技(002514。SZ)发布公告,公司拟以不超过296。21万元人民币的价格收购四川富骅新能源科技有限公司(下称富骅新能源)26的股权。同时,在满足各自发展理念果然没白等!全新一代奔驰C级上市,售32。5236。92万最近,一组全新一代奔驰C级的图片在网上曝光,据悉,该车推出4款配置车型,售价区间为32。52万36。92万。相信大家和小编一样都很期待这款汽车的表现,下面,我们一起来看看吧!首先来奥联电子主业优势突出转型求变,大股东增持彰显长期发展信心奥联电子(300585。SZ)10月25日公告,2021年前三季度公司实现营业收入3。49亿元,报告期内,公司一方面巩固在汽车动力电子控制零部件领域的优势,并入选了专精特新小巨人企新国都持续深耕电子支付领域具备多极盈利增长点伴随移动互联网的快速发展,移动支付市场步入成熟,预计全球移动支付市场将保持稳定的增长。根据Statista发布的FinTechReport2021DigitalPayments,到蓝思科技引领消费电子板块上涨,金属结构件业务高效推进今日,蓝思科技上涨3。39,消费电子概念板块整体上涨2。37,长信科技东山精密信维通信领益智造等个股分别上涨4。873。943。703。15。自蓝思科技10月25日晚间披露第三季度光伏行业添新秀,消费电子龙头蓝思科技正式入局11月3日晚,蓝思科技发布公告称,公司设立光伏业务全资子公司,注册资本10亿元。公司已充分掌握相关产品设备技术的基础上,并得到相关行业客户的认可。此外,公司还提前对光伏玻璃等产品进苏宁818发烧节大家电悟空榜海信电视海尔冰洗强势夺冠!苏宁818发烧节逐渐接近尾声,而消费者们的剁手热情在昨天迎来了井喷式上升,尤其在主场大家电行业中,各品牌在悟空榜上打得火热,为了取得更好的排名你追我赶,仅过了一天排名就发生了翻天覆海尔总裁周云杰面对工业互联网时代,海尔已做好准备时代的发展离不开制造业,在21世纪的今天,地球村概念的普及,全球已经进入了互联网时代,传统制造业也在积极寻求变革,努力跟上时代潮流,把握时代机遇。工业互联网概念在这个时候便应运而生
荣耀Play5值得拥有吗?荣耀Play5是一款主打轻薄的5G手机,机身仅为7。46mm,重量为179g的超薄设计深受年轻人喜欢。真空镀膜工艺的玻璃后盖,质感不错,更显得时尚。从性能来看,荣耀Play5搭载的OPPOFindX3Pro摄影师版将于9月16日正式发布2021年9月14日星期二,OPPO官宣重磅新品FindX3Pro摄影师版。这款新品将于9月16日的OPPO秋季新品发布会上正式发布。该产品的Slogan是献给总在拍照的你,寓意着今晚即将发布的ipadmini6是否值得买?大家期盼已久的ipadmini6很有可能会在明天凌晨1点的发布会上与大家见面。已经两年半没有换代的mini系列很可能会迎来巨大改变,那么这些改变是否值得我们掏钱买单呢?作为minivivox70详细参数vivox70参数配置近期vivox70的热度也是居高不下,很多小伙伴都想趁着这个时候入手一部手机,那么这款最新的手机变成了首选,但是不知道这款手机的配置如何,下面就和小编一起来看看吧!一参数配置二详细马斯克又整活了一张照片让山寨币暴涨1400币圈教父特斯拉CEO埃隆马斯克又整活了。9月12日,马斯克在社交平台晒了一张他新买的柴犬Floki的照片,配文Floki到家了。据媒体报道,随后一些名字含有Folki的山寨狗狗币价Visa首席执行官表示,Crypto可能在五年内变得非常受欢迎尽管只有十几年的历史,并且在公众视野下时间很短,但是Crypto获得了极大的欢迎,已经超过了2万亿美元的估值,击败了苹果和微软这样的大公司。近年来,公众对其采用也越来越广泛,根据目荣耀X20Max入网天玑11006000mAh电池近日,荣耀新机X20Max正式入网工信部,主打5G大屏,将搭载天玑1100处理器,7。2英寸屏幕,6000mAh大电池,并支持66W快充和双扬声器等。从目前曝光的渲染图来看,该机将真的这么持久?丰田全新电动车亮相开10年都可以不换电池近日,丰田官方宣布,在2030年前投资1。5万亿日元(约合人民币880亿元),用于下一代锂离子电池以及固态电池的研发。如此庞大的投入,丰田显然是做好准备一头扎进纯电动车市场。据了解Linux内核和Windows内核有什么区别目录一什么是内核?1。1内核的能力二操作系统分层三内核是如何工作的?四Linux的设计4。1MultitaskandSMP(Symmetricmultiprocessing)4。2提前看!苹果今晚发布会超全汇总,看完这篇今晚不用熬夜了今年关于发布会的爆料真的非常多。新iPhone外观大曝光,刘海摄像升级都让人激动新MacBookiPadmini参数都出来了,可以说,唯一的悬念就是价格了。对于不想熬夜的小伙伴们,从iPhone一代到最新的iPhone12系列价格汇总随着苹果iPhone13即将发布,不知不觉间苹果已经走过十多个年头了,在这十年里面iphone给消费者和世界的影响都是巨大的。虽然近几年iPhone挤牙膏式的更新一直深受消费者诟病