ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
来源:互联网 发布:sqlserver decimal 编辑:程序博客网 时间:2024/05/29 19:02
原文:http://blog.csdn.net/aitangyong/article/details/38172189
ExecutorService是JDK并发工具包提供的一个核心接口,相当于一个线程池,提供执行任务和管理生命周期的方法。ExecutorService接口中的大部分API都是比较容易上手使用的,本文主要介绍下invokeAll和invokeAll方法的特性和使用。我们先提供几个任务类:一个耗时任务,一个异常任务,一个短时任务。他们会在接下来的测试代码中使用。
- package tasks;
- import java.util.concurrent.Callable;
- import java.util.concurrent.TimeUnit;
- public class SleepSecondsCallable implements Callable<String>
- {
- private String name;
- private int seconds;
- public SleepSecondsCallable(String name, int seconds)
- {
- this.name = name;
- this.seconds = seconds;
- }
- public String call() throws Exception
- {
- System.out.println(name + ",begin to execute");
- try
- {
- TimeUnit.SECONDS.sleep(seconds);
- } catch (InterruptedException e)
- {
- System.out.println(name + " was disturbed during sleeping.");
- e.printStackTrace();
- return name + "_SleepSecondsCallable_failed";
- }
- System.out.println(name + ",success to execute");
- return name + "_SleepSecondsCallable_succes";
- }
- }
这是一个通过睡眠来模拟的耗时任务,该任务是可中断/可终止的任务,能够响应中断请求。
- package tasks;
- import java.util.concurrent.Callable;
- public class ExceptionCallable implements Callable<String>
- {
- private String name = null;
- public ExceptionCallable()
- {
- }
- public ExceptionCallable(String name)
- {
- this.name = name;
- }
- @Override
- public String call() throws Exception
- {
- System.out.println("begin to ExceptionCallable.");
- System.out.println(name.length());
- System.out.println("end to ExceptionCallable.");
- return name;
- }
- }
- package tasks;
- import java.util.Random;
- import java.util.concurrent.Callable;
- public class RandomTenCharsTask implements Callable<String>
- {
- @Override
- public String call() throws Exception
- {
- System.out.println("RandomTenCharsTask begin to execute...");
- StringBuffer content = new StringBuffer();
- String base = "abcdefghijklmnopqrstuvwxyz0123456789";
- Random random = new Random();
- for (int i = 0; i < 10; i++)
- {
- int number = random.nextInt(base.length());
- content.append(base.charAt(number));
- }
- System.out.println("RandomTenCharsTask complete.result=" + content);
- return content.toString();
- }
- }
1.测试invokeAny()
- /**
- * 提交的任务集合,一旦有1个任务正常完成(没有抛出异常),会终止其他未完成的任务
- */
- public static void invokeAny1() throws Exception
- {
- ExecutorService executorService = Executors.newFixedThreadPool(3);
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new SleepSecondsCallable("t1", 2));
- tasks.add(new SleepSecondsCallable("t2", 1));
- String result = executorService.invokeAny(tasks);
- System.out.println("result=" + result);
- executorService.shutdown();
- }
- /**
- * 没有1个正常完成的任务,invokeAny()方法抛出ExecutionException,封装了任务中元素的异常
- *
- */
- public static void invokeAny2() throws Exception
- {
- ExecutorService executorService = Executors.newFixedThreadPool(3);
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- String result = executorService.invokeAny(tasks);
- System.out.println("result=" + result);
- executorService.shutdown();
- }
- /**
- * 有异常的任务,有正常的任务,invokeAny()不会抛异常,返回最先正常完成的任务
- */
- public static void invokeAny3() throws Exception
- {
- ExecutorService executorService = Executors.newFixedThreadPool(3);
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- tasks.add(new SleepSecondsCallable("t1", 2));
- String result = executorService.invokeAny(tasks);
- System.out.println("result=" + result);
- executorService.shutdown();
- }
- /**
- * 还没有到超时之前,所以的任务都已经异常完成,抛出ExecutionException<br>
- * 如果超时前满,还没有没有完成的任务,抛TimeoutException
- */
- public static void invokeAnyTimeout() throws Exception
- {
- ExecutorService executorService = Executors.newFixedThreadPool(3);
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- tasks.add(new ExceptionCallable());
- String result = executorService.invokeAny(tasks, 2, TimeUnit.SECONDS);
- System.out.println("result=" + result);
- executorService.shutdown();
- }
- /**
- * Executes the given tasks, returning the result
- * of one that has completed successfully (i.e., without throwing
- * an exception), if any do. Upon normal or exceptional return,
- * tasks that have not completed are cancelled.
- * The results of this method are undefined if the given
- * collection is modified while this operation is in progress.
- *
- * @param tasks the collection of tasks
- * @return the result returned by one of the tasks
- * @throws InterruptedException if interrupted while waiting
- * @throws NullPointerException if tasks or any of its elements
- * are <tt>null</tt>
- * @throws IllegalArgumentException if tasks is empty
- * @throws ExecutionException if no task successfully completes
- * @throws RejectedExecutionException if tasks cannot be scheduled
- * for execution
- */
- <T> T invokeAny(Collection<? extends Callable<T>> tasks)
- throws InterruptedException, ExecutionException;
2.测试invokeAll()
这个方法相对来说比较好理解,就是执行任务列表中的所有任务,并返回与每个任务对应的Futue。也就是说,任务彼此之间不会相互影响,可以通过future跟踪每一个任务的执行情况,比如是否被取消,是正常完成,还是异常完成,这主要使用Future类提供的API。- public static void testInvokeAll() throws Exception
- {
- ExecutorService executorService = Executors.newFixedThreadPool(5);
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new SleepSecondsCallable("t1", 2));
- tasks.add(new SleepSecondsCallable("t2", 2));
- tasks.add(new RandomTenCharsTask());
- tasks.add(new ExceptionCallable());
- // 调用该方法的线程会阻塞,直到tasks全部执行完成(正常完成/异常退出)
- List<Future<String>> results = executorService.invokeAll(tasks);
- // 任务列表中所有任务执行完毕,才能执行该语句
- System.out.println("wait for the result." + results.size());
- executorService.shutdown();
- for (Future<String> f : results)
- {
- // isCanceled=false,isDone=true
- System.out.println("isCanceled=" + f.isCancelled() + ",isDone="
- + f.isDone());
- // ExceptionCallable任务会报ExecutionException
- System.out.println("task result=" + f.get());
- }
- }
第二种情况,测试限时版本的invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)
- /**
- * 可以通过Future.isCanceled()判断任务是被取消,还是完成(正常/异常)<br>
- * Future.isDone()总是返回true,对于invokeAll()的调用者来说,没有啥用
- */
- public static void testInvokeAllTimeout() throws Exception
- {
- ExecutorService executorService = Executors.newFixedThreadPool(5);
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new SleepSecondsCallable("t1", 2));
- tasks.add(new SleepSecondsCallable("t2", 2));
- tasks.add(new SleepSecondsCallable("t3", 3));
- tasks.add(new RandomTenCharsTask());
- List<Future<String>> results = executorService.invokeAll(tasks, 1,
- TimeUnit.SECONDS);
- System.out.println("wait for the result." + results.size());
- for (Future<String> f : results)
- {
- System.out.println("isCanceled=" + f.isCancelled() + ",isDone="
- + f.isDone());
- }
- executorService.shutdown();
- }
wait for the result.4
isCanceled=true,isDone=true
isCanceled=true,isDone=true
isCanceled=true,isDone=true
isCanceled=false,isDone=true
也就是说给定的超时期满,还没有完成的任务会被取消,即Future.isCancelled()返回true;在超时期之前,无论是正常完成还是异常终止的任务,Future.isCancelled()返回false。
第三种情况,测试在等待invokeAll执行完成之前,线程被中断。
- /**
- * 如果线程在等待invokeAll()执行完成的时候,被中断,会抛出InterruptedException<br>
- * 此时线程池会终止没有完成的任务,这主要是为了减少资源的浪费.
- */
- public static void testInvokeAllWhenInterrupt() throws Exception
- {
- final ExecutorService executorService = Executors.newFixedThreadPool(5);
- // 调用invokeAll的线程
- Thread invokeAllThread = new Thread() {
- @Override
- public void run()
- {
- List<Callable<String>> tasks = new ArrayList<Callable<String>>();
- tasks.add(new SleepSecondsCallable("t1", 2));
- tasks.add(new SleepSecondsCallable("t2", 2));
- tasks.add(new RandomTenCharsTask());
- // 调用线程会阻塞,直到tasks全部执行完成(正常完成/异常退出)
- try
- {
- List<Future<String>> results = executorService
- .invokeAll(tasks);
- System.out.println("wait for the result." + results.size());
- } catch (InterruptedException e)
- {
- System.out
- .println("I was wait,but my thread was interrupted.");
- e.printStackTrace();
- }
- }
- };
- invokeAllThread.start();
- Thread.sleep(200);
- invokeAllThread.interrupt();
- executorService.shutdown();
- }
ExecutorService.invokeAll()会抛出java.lang.InterruptedException,任务t1和t2都被终止抛出java.lang.InterruptedException: sleep interrupted。
也就是说一旦ExecutorService.invokeAll()方法产生了异常,线程池中还没有完成的任务会被取消执行。
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- java ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的源码阅读心得
- ExecutorService的invokeAny()方法测试
- Java线程之ExecutorService.invokeAny()
- executorService invokeAll 方法调用Callable
- 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- 深入学习理解java:ExecutorService invokeAll 任务的批量提交invokeAll两种方法的区别
- FutureTask、ExecutorService的使用
- ExecutorService 的使用
- ExecutorService的使用
- ExecutorService使用
- ExecutorService使用
- ExecutorService
- 死锁
- 用mysql workbench导出mysql数据库关系图
- 搜狐笔试题 马戏团
- Ubuntu安装ssh server(sshd)
- The declared package does not match the expected package
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
- Sublime Text 查找时排除指定的文件夹或文件
- 程序员修炼日志
- Git的基本配置
- 虚拟机类的加载过程
- FPGA零散笔记
- 统计之都统计分析和R语言方面的图书
- 配置Tableau Desktop连接SparkSQL
- 模型融合的主要方法