多线程(二)
主要的说明承接上面的InvokeAny/All 的说明,主要是代码的说明,接下来会对源码的说明:
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; } }
import java.util.Random; import java.util.concurrent.Callable; //短时任务,随即按产生10个数字 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(); } }
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"; } }
import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class Snippet { public static void main(String[] args) throws Exception{ // invokeAny1(); invokeAny2(); } /** * 提交的任务集合,一旦有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(); } /* 此invokeAny1()方法的输出结果: * t2,begin to execute * t1,begin to execute * t2,success to execute * java.lang.InterruptedException: sleep interrupted * result=t2_SleepSecondsCallable_succes * t1 was disturbed during sleeping. * 一个任务执行完成以后,会终止其他未完成的任务 */ /** * 没有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(); } /*invokeAny2()执行的结果: * begin to ExceptionCallable. * begin to ExceptionCallable. * begin to ExceptionCallable. * Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException * 具体的那个线程抛出来的错误,就无所谓了。 * / /** * 有异常的任务,有正常的任务,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(); } /* * 测试invokeAll * */ 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()); } } }