Java SE5的java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编程。Executor在客户端和执行任务之间提供了一个间接层,Executor代替客户端执行任务。Executor允许你管理异步任务的执行,而无须显式地管理线程的生命周期。Executor在Java SE5/6中时启动任务的优选方法。Executor引入了一些功能类来管理和使用线程Thread,其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。

创建线程池

Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定数目线程的线程池。

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

见类图,接口Executor只有一个方法execute,接口ExecutorService扩展了Executor并添加了一些生命周期管理的方法,如shutdown、submit等。一个Executor的生命周期有三种状态,运行 ,关闭 ,终止。

Callable,Future用于返回结果

Future代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞。FutureTask实现了Future和Runable。Callable代表一个有返回值得操作。

实例:并行计算求和:

    public class ConcurrentSum {  private int coreCpuNum;  private ExecutorService  executor;  private List<FutureTask<Long>> tasks = new ArrayList<FutureTask<Long>>();  public ConcurrentSum(){  coreCpuNum = Runtime.getRuntime().availableProcessors();  executor = Executors.newFixedThreadPool(coreCpuNum);  }  class SumCalculator implements Callable<Long>{  int nums[];  int start;  int end;  public SumCalculator(final int nums[],int start,int end){  this.nums = nums;  this.start = start;  this.end = end;  }  @Override  public Long call() throws Exception {  long sum =0;  for(int i=start;i<end;i++){  sum += nums[i];  }  return sum;  }  }  public long sum(int[] nums){  int start,end,increment;  // 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor   for(int i=0;i<coreCpuNum;i++){  increment = nums.length / coreCpuNum+1;  start = i*increment;  end = start+increment;  if(end > nums.length){  end = nums.length;   }  SumCalculator calculator = new SumCalculator(nums, start, end);  FutureTask<Long> task = new FutureTask<Long>(calculator);  tasks.add(task);  if(!executor.isShutdown()){  executor.submit(task);  }  }  return getPartSum();  }  public long getPartSum(){  long sum = 0;  for(int i=0;i<tasks.size();i++){  try {  sum += tasks.get(i).get();  } catch (InterruptedException e) {  e.printStackTrace();  } catch (ExecutionException e) {  e.printStackTrace();  }  }  return sum;  }  public void close(){  executor.shutdown();  }  public static void main(String[] args) {  int arr[] = new int[]{1, 22, 33, 4, 52, 61, 7, 48, 10, 11 };  long sum = new ConcurrentSum().sum(arr);  System.out.println("sum: " + sum);  }  }  

CompletionService

在上述例子中,getResult()方法的实现过程中,迭代了FutureTask的数组,如果任务还没有完成则当前线程会阻塞,如果我们希望任意任务完成后就把其结果加到result中,而不用依次等待每个任务完成,可以使用CompletionService。

它与ExecutorService最主要的区别在于submit的task不一定是按照加入时的顺序完成的。CompletionService对ExecutorService进行了包装,内部维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法其实就是Producer-Consumer中的Consumer。它会从Queue中取出Future对象,如果Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。所以,先完成的必定先被取出。这样就减少了不必要的等待时间。

实例:并行计算求和

    public class ConcurrentSum2 {  private int coreCpuNum;  private ExecutorService  executor;  private CompletionService<Long> completionService;  public ConcurrentSum2(){  //.....  }  class SumCalculator implements Callable<Long>{  //.....  }  public long sum(int[] nums){  int start,end,increment;  // 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor   for(int i=0;i<coreCpuNum;i++){  increment = nums.length / coreCpuNum+1;  start = i*increment;  end = start+increment;  if(end > nums.length){  end = nums.length;   }  SumCalculator task = new SumCalculator(nums, start, end);  if(!executor.isShutdown()){  completionService.submit(task);  }  }  return getPartSum();  }  public long getPartSum(){  long sum = 0;  for(int i=0;i<coreCpuNum;i++){  try {  sum += completionService.take().get();  } catch (InterruptedException e) {  e.printStackTrace();  } catch (ExecutionException e) {  e.printStackTrace();  }  }  return sum;  }  public void close(){  executor.shutdown();  }  }  

【Java并发编程】java并发框架Executor学习笔记相关推荐

  1. 学习笔记:Java 并发编程⑥_并发工具_JUC

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 配套资料: ...

  2. 【Java并发编程】并发编程大合集

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17539599 为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容 ...

  3. 《Java并发编程实践-第一部分》-读书笔记

    大家好,我是烤鸭: <Java并发编程实战-第一部分>-读书笔记. 第一章:介绍 1.1 并发历史: 多个程序在各自的进程中执行,由系统分配资源,如:内存.文件句柄.安全证书.进程间通信方 ...

  4. Java并发编程:并发容器之CopyOnWriteArrayList(转载)

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

  5. 【转】Java并发编程:并发容器之ConcurrentHashMap

    JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了 ...

  6. 并发编程——JUC并发编程知识脑图

    摘要 并发编程在软件编程中尤为突出和重要,在当今面试或工作中也是不可缺少的.作为一名高级java开发工程师,并发编程的技能已经成为了重要的一项.本博文将详细介绍并发编程中的知识点和知识脑图,帮助大家更 ...

  7. 【檀越剑指大厂--并发编程】并发编程总结

    并发编程 一.并发基础 1.什么是并行和并发? 并行,表示两个线程同时(同一时间)做事情. 并发,表示一会做这个事情,一会做另一个事情,存在着调度. 单核 CPU 不可能存在并行(微观上). 2.什么 ...

  8. 《Java Web开发入门很简单》学习笔记

    <Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...

  9. Java中如何创建自定义的注解学习笔记(MD版)

    概要 Java中如何创建自定义的注解学习笔记(MD版). 博客 博客地址:IT老兵驿站. 前言 记得这篇笔记还是在泉州的龙玲酒店记录的,是一个周六的晚上,坐飞机从上海到泉州,从笔记中能勾起一些旅游的回 ...

最新文章

  1. MVC 多级目录菜单
  2. 成员函数 静态变量做默认参数_Scala系列 (二)Scala的独有特性提高开发效率学会之后玩转函数式与OOP!!...
  3. 不同坐标系下角速度_坐标系统及常见坐标系
  4. PAT L1-048 矩阵A乘以B
  5. Netty常见面试题 与 答案
  6. 《程序员代码面试指南》第二章 链表问题 反转部分单向链表
  7. linux系统账户口令管理
  8. python爬虫06
  9. PyCharm——如果不小心修改了第三方库文件,怎么办?
  10. 伺服系统 计算机仿真,减摇鳍电伺服系统的计算机仿真研究-应用科技-哈尔滨工程大学.PDF...
  11. html怎么设置字体的透明度,CSS字体透明度怎么设置?
  12. 一个好用的PLC调试神器
  13. E-R图转化为关系模型
  14. Robust regression(稳健回归)
  15. 电脑端播放m3u8视频
  16. iPhone6 微信视频通话没有声音
  17. 跳动爱心代码-李峋同款爱心代码(升级版)
  18. java编程找出吸血鬼数字,Java 找到四位数的所有吸血鬼数字 基础代码实例
  19. 在centos8环境下用asterisk18配置pjsip和webrtc音视频通话教程(一)
  20. Delphi中使用TThread类实现多线程

热门文章

  1. linux内核的反复--一切都是过程
  2. 验证redis的主从复制
  3. android 再按一次退出程序
  4. 直接启动SDK Manager: $ADNROID_HOME/tools/android
  5. Linux中默认的JDK版本设置
  6. latex的资料ftp
  7. Python中生成一个指定长度的随机字符串实现示例
  8. (二)SpringBoot 整合 JPA
  9. Preference跳转activity出错Unable to find explicit activity class
  10. Minty Fresh : So You Want To Write An Orchestration?