首先介绍两个重要的接口,Executor和ExecutorService,定义如下:

  1. public interface Executor {
  2. void execute(Runnable command);
  3. }
  1. public interface ExecutorService extends Executor {
  2. //不再接受新任务,待所有任务执行完毕后关闭ExecutorService
  3. void shutdown();
  4. //不再接受新任务,直接关闭ExecutorService,返回没有执行的任务列表
  5. List<Runnable> shutdownNow();
  6. //判断ExecutorService是否关闭
  7. boolean isShutdown();
  8. //判断ExecutorService是否终止
  9. boolean isTerminated();
  10. //等待ExecutorService到达终止状态
  11. boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
  12. <T> Future<T> submit(Callable<T> task);
  13. //当task执行成功的时候future.get()返回result
  14. <T> Future<T> submit(Runnable task, T result);
  15. //当task执行成功的时候future.get()返回null
  16. Future<?> submit(Runnable task);
  17. //批量提交任务并获得他们的future,Task列表与Future列表一一对应
  18. <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
  19. throws InterruptedException;
  20. //批量提交任务并获得他们的future,并限定处理所有任务的时间
  21. <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
  22. long timeout, TimeUnit unit) throws InterruptedException;
  23. //批量提交任务并获得一个已经成功执行的任务的结果
  24. <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
  25. <T> T invokeAny(Collection<? extends Callable<T>> tasks,
  26. long timeout, TimeUnit unit)
  27. throws InterruptedException, ExecutionException, TimeoutException;
  28. }

为了配合使用上面的并发编程接口,有一个Executors工厂类,负责创建各类满足ExecutorService接口的线程池,具体如下: 
newFixedThreadPool:创建一个固定长度的线程池,线程池中线程的数量从1增加到最大值后保持不变。如果某个线程坏死掉,将会补充一个新的线程。 
newCachedThreadPool:创建长度不固定的线程池,线程池的规模不受限制,不常用。 
newSingleThreadExecutor:创建一个单线程的Executor,他其中有一个线程来处理任务,如果这个线程坏死掉,将补充一个新线程。 
newScheduledThreadPool:创建固定长度的线程池,以延时或定时的方式来执行任务。 

下面是Executor和ExecutorService中常用方法的示例:

  1. import java.util.ArrayList;
  2. import java.util.Collection;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import java.util.concurrent.Callable;
  6. import java.util.concurrent.Executor;
  7. import java.util.concurrent.ExecutorService;
  8. import java.util.concurrent.Executors;
  9. import java.util.concurrent.Future;
  10. import java.util.concurrent.TimeUnit;
  11. public class Demo{
  12. public static void main(String [] args){
  13. //--------Executor示例------------//
  14. Executor s=Executors.newSingleThreadExecutor();
  15. s.execute(new MyRunnableTask("1"));
  16. //--------ExecutorService示例------------//
  17. ExecutorService es=Executors.newFixedThreadPool(2);
  18. //--------get()示例------------//
  19. Future<String> future=es.submit(new MyCallableTask("10"));
  20. try{
  21. System.out.println(future.get());
  22. }catch(Exception e){}
  23. //--------get(timeout, timeunit)示例------------//
  24. future=es.submit(new MyCallableTask("11"));
  25. try{
  26. System.out.println(future.get(500,TimeUnit.MILLISECONDS));
  27. }catch(Exception e){
  28. System.out.println("cancle because timeout");
  29. }
  30. //--------invokeAll(tasks)示例------------//
  31. List<MyCallableTask> myCallableTasks=new ArrayList<MyCallableTask>();
  32. for(int i=0;i<6;i++){
  33. myCallableTasks.add(new MyCallableTask(i+""));
  34. }
  35. try {
  36. List<Future<String>> results = es.invokeAll(myCallableTasks);
  37. Iterator<Future<String>> iterator=results.iterator();
  38. while(iterator.hasNext()){
  39. future=iterator.next();
  40. System.out.println(future.get());
  41. }
  42. } catch (Exception e) {}
  43. //--------invokeAll(tasks,timeout,timeunit))示例------------//
  44. try {
  45. //限定执行时间为2100ms,每个任务需要1000ms,线程池的长度为2,因此最多只能处理4个任务。一共6个任务,有2个任务会被取消。
  46. List<Future<String>> results = es.invokeAll(myCallableTasks,2100,TimeUnit.MILLISECONDS);
  47. Iterator<Future<String>> iterator=results.iterator();
  48. while(iterator.hasNext()){
  49. future=iterator.next();
  50. if(!future.isCancelled())
  51. System.out.println(future.get());
  52. else
  53. System.out.println("cancle because timeout");
  54. }
  55. } catch (Exception e) {}
  56. es.shutdown();
  57. }
  58. }
  59. class MyRunnableTask implements Runnable{
  60. private String name;
  61. public MyRunnableTask(String name) {
  62. this.name=name;
  63. }
  64. @Override
  65. public void run() {
  66. try {
  67. Thread.sleep(1000);
  68. } catch (InterruptedException e) {
  69. e.printStackTrace();
  70. }
  71. System.out.println("runnable task--"+name);
  72. }
  73. }
  74. class MyCallableTask implements Callable<String>{
  75. private String name;
  76. public MyCallableTask(String name) {
  77. this.name=name;
  78. }
  79. @Override
  80. public String call() throws Exception {
  81. try {
  82. Thread.sleep(1000);
  83. } catch (InterruptedException e) {}
  84. StringBuilder sb=new StringBuilder("callable task--");
  85. return sb.append(name).toString();
  86. }
  87. }

上面的ExecutorSerivce接口中的invokeAll(tasks)方法用于批量执行任务,并且将结果按照task列表中的顺序返回。此外,还存在一个批量执行任务的接口CompletionTask。ExecutorCompletionService是实现CompletionService接口的一个类,该类的实现原理很简单: 

用Executor类来执行任务,同时把在执行任务的Future放到BlockingQueue<Future<V>>队列中。该类实现的关键就是重写FutureTask类的done()方法,FutureTask类的done()方法是一个钩子函数(关于钩子函数,请读者自行查询),done()方法在FutureTask任务被执行的时候被调用。 

ExecutorCompletionService类的核心代码如下:

  1. public Future<V> submit(Runnable task, V result) {
  2. if (task == null) throw new NullPointerException();
  3. RunnableFuture<V> f = newTaskFor(task, result);
  4. executor.execute(new QueueingFuture(f));
  5. return f;
  6. }
  7. private class QueueingFuture extends FutureTask<Void> {
  8. QueueingFuture(RunnableFuture<V> task) {
  9. super(task, null);
  10. this.task = task;
  11. }
  12. protected void done() { completionQueue.add(task); }
  13. private final Future<V> task;
  14. }

其中的done()方法定义如下:

  1. /**
  2. * Protected method invoked when this task transitions to state
  3. * <tt>isDone</tt> (whether normally or via cancellation). The
  4. * default implementation does nothing.  Subclasses may override
  5. * this method to invoke completion callbacks or perform
  6. * bookkeeping. Note that you can query status inside the
  7. * implementation of this method to determine whether this task
  8. * has been cancelled.
  9. */
  10. protected void done() { }

ExecutorCompletionService的使用示例如下:

    1. import java.util.concurrent.Callable;
    2. import java.util.concurrent.CompletionService;
    3. import java.util.concurrent.ExecutionException;
    4. import java.util.concurrent.ExecutorCompletionService;
    5. import java.util.concurrent.Executors;
    6. import java.util.concurrent.Future;
    7. public class Demo{
    8. public static void main(String [] args) throws InterruptedException, ExecutionException{
    9. CompletionService<String> cs=new ExecutorCompletionService<String>(
    10. Executors.newFixedThreadPool(2));
    11. for(int i=0;i<6;i++){
    12. cs.submit(new MyCallableTask(i+""));
    13. }
    14. for(int i=0;i<6;i++){
    15. Future<String> future=cs.take();
    16. //Retrieves and removes the Future representing the next completed task,
    17. //waiting if none are yet present.
    18. System.out.println(future.get());
    19. }
    20. }
    21. }
    22. class MyCallableTask implements Callable<String>{
    23. private String name;
    24. public MyCallableTask(String name) {
    25. this.name=name;
    26. }
    27. @Override
    28. public String call() throws Exception {
    29. try {
    30. Thread.sleep(1000);
    31. } catch (InterruptedException e) {}
    32. StringBuilder sb=new StringBuilder("callable task--");
    33. return sb.append(name).toString();
    34. }
    35. }

java并发编程框架 Executor ExecutorService invokeall的更多相关文章

  1. java并发编程:Executor、Executors、ExecutorService

    1.Executor和ExecutorService Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable comma ...

  2. Java并发编程--4.Executor框架

    简介 Executor框架是启动,管理线程的API, 它的内部实现是线程池机制,它有很多好处,比如使任务提交和任务执行解耦合,防止this逃逸:它的主要API包括: Executor,  Execut ...

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

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

  4. 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结

    <Java并发编程实战>和<Java并发编程的艺术>           Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...

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

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

  6. Java并发编程 - Executor,Executors,ExecutorService, CompletionServie,Future,Callable

    一.Exectuor框架简介 Java从1.5版本开始,为简化多线程并发编程,引入全新的并发编程包:java.util.concurrent及其并发编程框架(Executor框架). Executor ...

  7. Java并发编程(08):Executor线程池框架

    本文源码:GitHub·点这里 || GitEE·点这里 一.Executor框架简介 1.基础简介 Executor系统中,将线程任务提交和任务执行进行了解耦的设计,Executor有各种功能强大的 ...

  8. java并发编程-Executor框架

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

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

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

随机推荐

  1. python基础-安装篇

    1.安装之前我们要先去python的官网下载python的安装包 下载地址:https://www.python.org/downloads/ Python 官网有两个版本一个是3.5.2(最新版)一 ...

  2. 解决asp.net中“从客户端中检测到有潜在危险的Request.Form值”的错误

    修改Web.config,增加requestValidationMode="2.0"属性值 <system.web> <httpRuntime requestVa ...

  3. iPhone doesn’t support any of GongShangJ.app’s architectures. You can add iPhone’s armv7s architectu

    iPhone doesn't support any of GongShangJ.app's architectures. You can add iPhone's armv7s architectu

  4. Redis集合相关命令

    1.无序集合集合的特性:①确定性②互异性③无序性redis的set是string类型的无序集合set元素最大可以包含(2^32-1)个元素 sadd key value1....valueN 将将元素 ...

  5. Linux镜像资源收集

    1.企业 搜狐开源镜像站: http://mirrors.sohu.com/ 网易开源镜像站: http://mirrors.163.com/ 阿里开源镜像站: http://mirrors.aliy ...

  6. 1.部分(苹果)移动端的cookie不支持中文字符,2.从json字符串变为json对象时,只支持对象数组

    1.移动端的cookie不支持中文字符.可以用编码,解码的方式解决. 2.json字符串变成相应 的,json对象数组字符串.就这样 3.不同客户端(移动端.电脑)的请求,在C#服务端的取时间的格式竟 ...

  7. webAppRootKey

    web.xml中webAppRootKey ------------------------------------------------------------------------------ ...

  8. ACdream 1020 The Game about KILL

    找规律. 11 3 1 3 5 7 1 3 5 7 9 11 13 15 ....... #pragma comment(linker, "/STACK:1024000000,1024000 ...

  9. hadoop中,combine、partition、shuffle作用分别是什么?

    combine和partition都是函数,中间的步骤应该只有shuffle! combine分为map端和reduce端,作用是把同一个key的键值对合并在一起,可以自定义的.combine函数把一 ...

  10. Hadoop安装教程

    单机.伪分布式:http://dblab.xmu.edu.cn/blog/install-hadoop/ 集群:http://dblab.xmu.edu.cn/blog/install-hadoop- ...