from: https://www.cnblogs.com/shipengzhi/articles/2067154.html

import java.util.concurrent.*;
public class ConcurrentCalculator2 { //from: https://www.cnblogs.com/shipengzhi/articles/2067154.html
private ExecutorService executorService;
private CompletionService<Long> completionService;
private int cpuCoreNumber; public ConcurrentCalculator2() {
cpuCoreNumber = Runtime.getRuntime().availableProcessors();
executorService = Executors.newFixedThreadPool(cpuCoreNumber);
completionService = new ExecutorCompletionService<Long>(executorService);
} public Long sum(final int[] numbers) {
for (int i = 0; i < cpuCoreNumber; i++) { //(页数)根据CPU核心个数拆分任务,创建FutureTask并提交到Executor
int increment = numbers.length / cpuCoreNumber + 1; //(每页多少条)
int start = increment * i; //首条数据-->当前页 的
int end = increment * i + increment; //首条数据-->(当前页+1)的
if (end > numbers.length)
end = numbers.length;
SumCalculator subCalc = new SumCalculator(numbers, start, end, (i+1));
if (!executorService.isShutdown()) {
completionService.submit(subCalc);
}
}
System.out.println("所有计算任务提交完毕, 主线程接着干其他事情!");
return getResult();
} public Long getResult() { //迭代每个只任务,获得部分和,相加返回
Long result = 0l;
int index =0;
System.out.println("-->2-"+ Thread.currentThread().getName()+"线程 List<Future<Long>>集合中的第一个元素开始遍历之前【就开始 全部执行掉MyCallable构造方法(不一定按集合内部顺序)!】");
for (int i = 0; i < cpuCoreNumber; i++) {
try {
index++;
Long subSum = completionService.take().get();
System.out.println("-->4-"+Thread.currentThread().getName()+"线程 "+"-List<Future<Long>>集合遍历ing(一定按集合内部顺序)【有时候3和4会<成对>交叉执行】-- 打印第:"+index+"页累计的和:" + subSum);
result += subSum;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("-->5-总结-->线程的实现方法总是先一步于List<Future<Long>>的遍历(线程的impl分页计算各页的总和,List<Future>负责把所有页的和累加!");
return result; } public void close() {
executorService.shutdown();
} class SumCalculator implements Callable<Long> {//Runnable
private int[] numbers;
private int start;
private int end;
private int index; public SumCalculator(final int[] numbers, int start, int end, int index) {
this.numbers = numbers;
this.start = start;
this.end = end;
this.index = index;
System.out.println("-->1-"+Thread.currentThread().getName() +"线程-生成子线程计算任务(调用构造函数)第 "+ index +"次");
} @Override
public Long call() throws Exception {
Long sum = 0l;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
//子线程-->休眠5秒钟,观察主线程行为,预期的结果是主线程会继续执行,到要取得FutureTask的结果是等待直至完成。
Thread.sleep(3000); System.out.println("-->3-" + Thread.currentThread().getName() + "线程执行计算任务 打印current数据:" +"startIndex:"+ start + ";endIndex:" + end+ ";sum:" + "=" + sum);
return sum;
}
}
public static void main(String[] args) {
int[] numbers = new int[] { 0, 1, 2 };
ConcurrentCalculator2 calculator = new ConcurrentCalculator2();
Long sum = calculator.sum(numbers);
System.out.println("-->10-res:"+sum);
calculator.close();
} /** * Callable 和 Future接口 * Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。 * Callable和Runnable有几点不同: * (1)Callable规定的方法是call(),而Runnable规定的方法是run(). * (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。 * (3)call()方法可抛出异常,而run()方法是不能抛出异常的。 * (4)运行Callable任务可拿到一个Future对象, * Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。 * 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。 */
}

java并发编程-Executor框架 + Callable + Future的更多相关文章

  1. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  2. (转)java并发编程--Executor框架

    本文转自https://www.cnblogs.com/MOBIN/p/5436482.html java并发编程--Executor框架 只要用到线程,就可以使用executor.,在开发中如果需要 ...

  3. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  4. java并发编程-Executor框架

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...

  5. Java 并发编程 Executor 框架

    本文部分摘自<Java 并发编程的艺术> Excutor 框架 1. 两级调度模型 在 HotSpot VM 的线程模型中,Java 线程被一对一映射为本地操作系统线程.在上层,Java ...

  6. Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况

    如题 (总结要点) 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况: V get (long timeout, TimeUnit ...

  7. Java并发编程-Executor框架(转)

    本文转自http://blog.csdn.net/chenchaofuck1/article/details/51606224 感谢作者 我们在传统多线程编程创建线程时,常常是创建一些Runnable ...

  8. java并发编程--Executor框架(一)

    摘要:        Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程 ...

  9. Java并发编程-Executor框架集

    Executor框架集对线程调度进行了封装,将任务提交和任务执行解耦. 它提供了线程生命周期调度的所有方法,大大简化了线程调度和同步的门槛. Executor框架集的核心类图如下: 从上往下,可以很清 ...

随机推荐

  1. C# DataTable列名不区分大小写

    一直很纠结的就是DataTable的列名如何才能规范,从Oracle取出的DataTable都是大写,最后尝试了一下,原来C#的DataTable列名并不区分大小写,具体例子如下: DataTable ...

  2. CRISPR基因编辑

    2007年,一家酸奶公司发现一种细菌拥有抵御病毒的特殊防御机制.2012年,细菌的这种机制就被科学家阐述清楚,2013年这一领域快速增长.它被视为分子生物学的一个奇迹,事实上,它并非仅对生物学家产生革 ...

  3. ArcGIS 要素闪烁

    ArcGIS 要素闪烁 通过双击要素图例,闪烁定位到要素,并且闪烁一段时间: IFeatureLayer featureLayer = layer as IFeatureLayer;          ...

  4. English trip -- VC(情景课) 7 B Clothing 服装

    xu言: 不要使用中式的思维去思考西方的语义!!!切记切记 words a tie   领带 a blouse  女士衬衣 a sweater  毛衣 a skirt  短裙 a jacket   夹 ...

  5. 20170707xlVBA多区域拆分多表保持行高列宽

    Public Sub 多个区域拆分到多表() AppSettings On Error GoTo ErrHandler Dim StartTime, UsedTime As Variant Start ...

  6. 2018焦作网络赛Give Candies

    一开始忽略了欧拉定理指数部分是modphi(n-1)没有memset,减法后面没加0:

  7. python-day3笔记

    1.通信是软件(计算机)与软件(计算机)之间的通信 2.网络指的是: 一:计算机与计算机之间通过物理连接介质(网络设备)连接到一起:光纤--物理连接介质,和网线一样. 二:计算机与计算机之间基于网络协 ...

  8. TCP/IP四层与OSI七层模型

      OSI七层和TCP/IP四层的关系 1.1 OSI引入了服务.接口.协议.分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型. 1.2 OSI先有模型,后有协议,先有标准,后进行实 ...

  9. iOS开发-开发文档安装

    iOS开发肯定离不开开发文档,苹果有在线帮助文档,xCode其实可以下载模拟器文档和iOS8.1文档的,不过下载的速度实在不敢恭维,而且比较头疼的是不显示下载进度条的,苹果的开发文档都是放在)/应用程 ...

  10. jsp jsp的基本语法

    jsp模板元素  jsp页面中的HTML 内容称为JSP模板元素  jsp模板元素定义了网页的基本骨架,即定义了页面结构和外观 jsp表达式   jsp脚本表达式用于将程序数据输出到客户端   语法& ...