资讯专栏INFORMATION COLUMN

java并发编程学习之线程池-AbstractExecutorService(二)

Jokcy / 748人阅读

摘要:抽象类,实现了的接口。将任务封装成提交任务主要方法在任务是否超时超时时间任务书用于存放结果的,先完成的放前面。

AbstractExecutorService抽象类,实现了ExecutorService的接口。

newTaskFor

将任务封装成FutureTask

</>复制代码

  1. protected RunnableFuture newTaskFor(Runnable runnable, T value) {
  2. return new FutureTask(runnable, value);
  3. }
  4. protected RunnableFuture newTaskFor(Callable callable) {
  5. return new FutureTask(callable);
  6. }
submit

提交任务

</>复制代码

  1. public Future submit(Runnable task) {
  2. if (task == null) throw new NullPointerException();
  3. RunnableFuture ftask = newTaskFor(task, null);
  4. execute(ftask);
  5. return ftask;
  6. }
  7. public Future submit(Runnable task, T result) {
  8. if (task == null) throw new NullPointerException();
  9. RunnableFuture ftask = newTaskFor(task, result);
  10. execute(ftask);
  11. return ftask;
  12. }
  13. public Future submit(Callable task) {
  14. if (task == null) throw new NullPointerException();
  15. RunnableFuture ftask = newTaskFor(task);
  16. execute(ftask);
  17. return ftask;
  18. }
invokeAny

主要方法在doInvokeAny

</>复制代码

  1. //tasks任务
  2. //timed是否超时
  3. //nanos超时时间
  4. private T doInvokeAny(Collection> tasks,
  5. boolean timed, long nanos)
  6. throws InterruptedException, ExecutionException, TimeoutException {
  7. if (tasks == null)
  8. throw new NullPointerException();
  9. int ntasks = tasks.size();//任务书
  10. if (ntasks == 0)
  11. throw new IllegalArgumentException();
  12. ArrayList> futures = new ArrayList>(ntasks);
  13. //用于存放结果的,先完成的放前面。所以第一个任务没完成的时候,会继续提交后续任务
  14. ExecutorCompletionService ecs =
  15. new ExecutorCompletionService(this);
  16. try {
  17. //异常信息
  18. ExecutionException ee = null;
  19. //过期时间
  20. final long deadline = timed ? System.nanoTime() + nanos : 0L;
  21. Iterator> it = tasks.iterator();//获取第一个任务
  22. 提交任务
  23. futures.add(ecs.submit(it.next()));
  24. --ntasks;//因为提交了一个,任务数-1
  25. int active = 1;//正在执行的任务
  26. for (;;) {
  27. Future f = ecs.poll();
  28. if (f == null) {//第一个没完成
  29. if (ntasks > 0) {//还有没提交的任务
  30. --ntasks;//任务数-1
  31. futures.add(ecs.submit(it.next()));//提交任务
  32. ++active;//正在执行的任务+1
  33. }
  34. else if (active == 0)//当前没任务了,但是都失败了,异常被捕获了
  35. break;
  36. else if (timed) {
  37. f = ecs.poll(nanos, TimeUnit.NANOSECONDS);//等待
  38. if (f == null)//返回空,超时抛出异常,结束
  39. throw new TimeoutException();
  40. nanos = deadline - System.nanoTime();//剩余时间
  41. }
  42. else
  43. f = ecs.take();//阻塞等待获取
  44. }
  45. if (f != null) {//说明已经执行完
  46. --active;//任务数-1
  47. try {
  48. return f.get();//返回执行结果
  49. } catch (ExecutionException eex) {
  50. ee = eex;
  51. } catch (RuntimeException rex) {
  52. ee = new ExecutionException(rex);
  53. }
  54. }
  55. }
  56. if (ee == null)
  57. ee = new ExecutionException();
  58. throw ee;
  59. } finally {
  60. //取消其他任务,毕竟第一个结果已经返回了
  61. for (int i = 0, size = futures.size(); i < size; i++)
  62. futures.get(i).cancel(true);
  63. }
  64. }
  65. public T invokeAny(Collection> tasks)
  66. throws InterruptedException, ExecutionException {
  67. try {
  68. return doInvokeAny(tasks, false, 0);
  69. } catch (TimeoutException cannotHappen) {
  70. assert false;
  71. return null;
  72. }
  73. }
  74. public T invokeAny(Collection> tasks,
  75. long timeout, TimeUnit unit)
  76. throws InterruptedException, ExecutionException, TimeoutException {
  77. return doInvokeAny(tasks, true, unit.toNanos(timeout));
  78. }
invokeAll

返回所有任务的结果

</>复制代码

  1. public List> invokeAll(Collection> tasks)
  2. throws InterruptedException {
  3. if (tasks == null)
  4. throw new NullPointerException();
  5. ArrayList> futures = new ArrayList>(tasks.size());//
  6. boolean done = false;
  7. try {
  8. for (Callable t : tasks) {//封装任务,并提交
  9. RunnableFuture f = newTaskFor(t);
  10. futures.add(f);
  11. execute(f);
  12. }
  13. for (int i = 0, size = futures.size(); i < size; i++) {
  14. Future f = futures.get(i);
  15. if (!f.isDone()) {
  16. try {
  17. f.get();//阻塞,等待结果
  18. } catch (CancellationException ignore) {
  19. } catch (ExecutionException ignore) {
  20. }
  21. }
  22. }
  23. done = true;
  24. return futures;
  25. } finally {
  26. if (!done)//有异常,取消
  27. for (int i = 0, size = futures.size(); i < size; i++)
  28. futures.get(i).cancel(true);
  29. }
  30. }
  31. public List> invokeAll(Collection> tasks,
  32. long timeout, TimeUnit unit)
  33. throws InterruptedException {
  34. if (tasks == null)
  35. throw new NullPointerException();
  36. long nanos = unit.toNanos(timeout);
  37. ArrayList> futures = new ArrayList>(tasks.size());
  38. boolean done = false;
  39. try {
  40. for (Callable t : tasks)
  41. futures.add(newTaskFor(t));
  42. final long deadline = System.nanoTime() + nanos;
  43. final int size = futures.size();
  44. // Interleave time checks and calls to execute in case
  45. // executor doesn"t have any/much parallelism.
  46. for (int i = 0; i < size; i++) {
  47. execute((Runnable)futures.get(i));
  48. nanos = deadline - System.nanoTime();
  49. if (nanos <= 0L)
  50. return futures;//每个提交都要判断,超时了返回Future
  51. }
  52. for (int i = 0; i < size; i++) {
  53. Future f = futures.get(i);
  54. if (!f.isDone()) {
  55. if (nanos <= 0L)
  56. return futures;
  57. try {
  58. f.get(nanos, TimeUnit.NANOSECONDS);
  59. } catch (CancellationException ignore) {
  60. } catch (ExecutionException ignore) {
  61. } catch (TimeoutException toe) {
  62. return futures;
  63. }
  64. nanos = deadline - System.nanoTime();
  65. }
  66. }
  67. done = true;
  68. return futures;
  69. } finally {
  70. if (!done)
  71. for (int i = 0, size = futures.size(); i < size; i++)
  72. futures.get(i).cancel(true);
  73. }
  74. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75708.html

相关文章

  • java并发编程习之线程-预定义线程(四)

    摘要:系统预定了几个线程池,不过建议手动创建,以防止错误创建消耗资源,比如创建太多线程或者固定线程数量,无界队列固定线程数量,数量为,无界队列,会按顺序执行不限制线程数量,使用队列,使用于短任务基于用于周期性执行任务示例第一个是,第二个是第一 系统预定了几个线程池,不过建议手动创建,以防止错误创建消耗资源,比如创建太多线程或者OOM FixedThreadPool 固定线程数量,无界队列 p...

    suemi 评论0 收藏0
  • java并发编程习之线程-ThreadPoolExecutor(三)

    摘要:是所有线程池实现的父类,我们先看看构造函数构造参数线程核心数最大线程数线程空闲后,存活的时间,只有线程数大于的时候生效存活时间的单位任务的阻塞队列创建线程的工程,给线程起名字当线程池满了,选择新加入的任务应该使用什么策略,比如抛异常丢弃当前 ThreadPoolExecutor ThreadPoolExecutor是所有线程池实现的父类,我们先看看构造函数 构造参数 corePool...

    阿罗 评论0 收藏0
  • java并发编程习之线程-Executor和ExecutorService(一)

    摘要:接口用于提交任务接口继承了接口设置线程的状态,还没执行的线程会被中断设置线程的状态,尝试停止正在进行的线程当调用或方法后返回为当调用方法后,并且所有提交的任务完成后返回为当调用方法后,成功停止后返回为当前线程阻塞,直到线程执行完时间到被中断 Executor接口 void execute(Runnable command)//用于提交command任务 ExecutorService接...

    liuchengxu 评论0 收藏0
  • java并发编程习之线程的生命周期-start(

    摘要:与执行方法,是用来启动线程的,此时线程处于就绪状态,获得调度后运行方法。执行方法,相对于普通方法调用,在主线程调用。程序是顺序执行的,执行完才会执行下面的程序。 start与run 执行start方法,是用来启动线程的,此时线程处于就绪状态,获得调度后运行run方法。run方法执行结束,线程就结束。 执行run方法,相对于普通方法调用,在主线程调用。程序是顺序执行的,执行完才会执行下...

    bigdevil_s 评论0 收藏0
  • Java线程习(八)线程与Executor 框架

    摘要:一使用线程池的好处线程池提供了一种限制和管理资源包括执行一个任务。每个线程池还维护一些基本统计信息,例如已完成任务的数量。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。使用无界队列作为线程池的工作队列会对线程池带来的影响与相同。 历史优质文章推荐: Java并发编程指南专栏 分布式系统的经典基础理论 可能是最漂亮的Spring事务管理详解 面试中关于Java虚拟机(jvm)的问...

    cheng10 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<