首先介绍两个重要的接口,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. php笔记(四)PHP类和对象之对象继承

    建立一个Truck类,扩展Car类,并覆盖speedUp方法,使速度累加50 <?php class Car { public $speed = 0; //汽车的起始速度是0 public fu ...

  2. Java基础之异常

    1.异常的概念 异常:程序在运行时出现的不正常情况,也可以说是出现的问题: Java中的异常:出现的不正常的问题也是一类事物,这类事物有一些共性的东西,比如有名称,有产生的原因等,将这些共性的部分抽取 ...

  3. html绑定

    目的 html绑定可以绑定DOM元素内的HTML内容. 示例: <div data-bind="html: details"></div> <scri ...

  4. nginx 403

    location / { autoindex on; } chown -R www-data:www-data /var/www usermod -a -G www-data rootnano /et ...

  5. 初始化一个本地GIT仓储

    简单总结下 // 定位到仓储文件夹目录 $ cd /dir // 初始化本地仓储 $ git init ``` 添加本地GIT忽略清单文件.gitignore```// 添加OS X中系统文件.DS_ ...

  6. PHP来实现文件上传

    文件php <?phpif ($_FILES["file"]["error"] > 0){ echo '错误: ' . $_FILES[" ...

  7. (十)foreac遍历、break和countinue以及标签和switch循环

    foreach语法,表示不必创建int变量去对由访问项构成的序列进行计数,foreach将自动产生每一项. 例:输出数组的所有元素. float f[]=new float[5]; f[0]=1.0f ...

  8. Android实现图片宽度100%ImageView宽度且高度按比例自动伸缩

    在ListView中为了实现图片宽度100%适应ImageView容器宽度,让高度自动按比例伸缩功能,查了很多资料,搞了一下午都没找出个现成的办法,不过貌似有个结论了,就是: Android自身不能实 ...

  9. CodeForces 705C Thor

    开30W个vector将数字归类,每一类数字开一个指针P,记录已经阅读到哪一个了,还可以开一个优先队列维护这些指针P. #pragma comment(linker, "/STACK:102 ...

  10. Android 消息传递之Bundle的使用——实现object对象传输(一)

    UI更新--消息处理massage 对于安卓内部消息得处理,实现对界面UI得更新操作,不能在线程中直接更新ui.至于为什么不能,在学习安卓开发的时候,在线程中操作会使程序崩溃. 为什么,可以看看诸多大 ...