CompletionService的异常处理
一、采用take()方法时发生异常
示例代码:
情况一:异常比另一个正确任务,较晚出现,正确任务的结果会打印出
import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyCompletionServiceException { public static void main(String[] args) { // TODO 自动生成的方法存根 ExecutorService executor=Executors.newCachedThreadPool(); CompletionService<String> comservice=new ExecutorCompletionService<String>(executor); MyException_one callone=new MyException_one(); MyException_two calltwo=new MyException_two(); comservice.submit(callone); comservice.submit(calltwo); try { // Thread.sleep(3000); System.out.println(comservice.take().get()); System.out.println(comservice.take().get()); // System.out.println(comservice.poll().get()); // System.out.println(comservice.poll().get()); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (ExecutionException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } class MyException_one implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(2000); if(true){ throw new Exception("抛出异常"); } return "one"; } } class MyException_two implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(1000); return "two"; } }
运行结果:
import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyCompletionServiceException { public static void main(String[] args) { // TODO 自动生成的方法存根 ExecutorService executor=Executors.newCachedThreadPool(); CompletionService<String> comservice=new ExecutorCompletionService<String>(executor); MyException_one callone=new MyException_one(); MyException_two calltwo=new MyException_two(); comservice.submit(callone); comservice.submit(calltwo); try { // Thread.sleep(3000); System.out.println(comservice.take().get()); System.out.println(comservice.take().get()); // System.out.println(comservice.poll().get()); // System.out.println(comservice.poll().get()); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (ExecutionException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } class MyException_one implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(2000); if(true){ throw new Exception("抛出异常"); } return "one"; } } class MyException_two implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(1000); return "two"; } }
当只采用take()方法,而不使用get()方法时不出现异常,改为:
System.out.println(comservice.take().get()); System.out.println(comservice.take());
运行结果:
two java.util.concurrent.FutureTask@1f96302
情况二:
异常比另一个正确任务较早出现,这时不会打印出另一个正确任务的结果
示例代码(贴出有修改的地方):
class MyException_one implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(1000); if(true){ throw new Exception("抛出异常"); } return "one"; } } class MyException_two implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(3000); return "two"; } }
运行结果:
java.util.concurrent.ExecutionException: java.lang.Exception: 抛出异常 at java.util.concurrent.FutureTask.report(Unknown Source) at java.util.concurrent.FutureTask.get(Unknown Source) at mycompletionservice.MyCompletionServiceException.main(MyCompletionServiceException.java:23) Caused by: java.lang.Exception: 抛出异常 at mycompletionservice.MyException_one.call(MyCompletionServiceException.java:44) at mycompletionservice.MyException_one.call(MyCompletionServiceException.java:1) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
二、采用poll()方法时发生异常
情况一:异常比另一个正确任务,较晚出现,正确任务的结果会打印出
示例代码:
import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyCompletionServiceException { public static void main(String[] args) { // TODO 自动生成的方法存根 ExecutorService executor=Executors.newCachedThreadPool(); CompletionService<String> comservice=new ExecutorCompletionService<String>(executor); MyException_one callone=new MyException_one(); MyException_two calltwo=new MyException_two(); comservice.submit(calltwo); comservice.submit(callone); try { Thread.sleep(3000); // System.out.println(comservice.take().get()); // System.out.println(comservice.take().get()); System.out.println(comservice.poll().get()); System.out.println(comservice.poll().get()); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (ExecutionException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } class MyException_one implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(2000); if(true){ throw new Exception("抛出异常"); } return "one"; } } class MyException_two implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(1000); return "two"; } }
运行结果:
two java.util.concurrent.ExecutionException: java.lang.Exception: 抛出异常 at java.util.concurrent.FutureTask.report(Unknown Source) at java.util.concurrent.FutureTask.get(Unknown Source) at mycompletionservice.MyCompletionServiceException.main(MyCompletionServiceException.java:26) Caused by: java.lang.Exception: 抛出异常 at mycompletionservice.MyException_one.call(MyCompletionServiceException.java:44) at mycompletionservice.MyException_one.call(MyCompletionServiceException.java:1) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
同样不是get()时不会出现异常
情况二:
异常比另一个正确任务较早出现,这时不会打印出另一个正确任务的结果
示例代码:
class MyException_one implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(1000); if(true){ throw new Exception("抛出异常"); } return "one"; } } class MyException_two implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(2000); return "two"; } }
运行结果:
class MyException_one implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(1000); if(true){ throw new Exception("抛出异常"); } return "one"; } } class MyException_two implements Callable<String>{ @Override public String call() throws Exception { // TODO 自动生成的方法存根 Thread.sleep(2000); return "two"; } }
import java.util.concurrent.Callable;import java.util.concurrent.CompletionService;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorCompletionService;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;
public class MyCompletionServiceException {
public static void main(String[] args) {// TODO 自动生成的方法存根ExecutorService executor=Executors.newCachedThreadPool();CompletionService<String> comservice=new ExecutorCompletionService<String>(executor);MyException_one callone=new MyException_one();MyException_two calltwo=new MyException_two();comservice.submit(calltwo);comservice.submit(callone);try {Thread.sleep(3000);//System.out.println(comservice.take().get());//System.out.println(comservice.take().get());System.out.println(comservice.poll().get());System.out.println(comservice.poll().get());} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();} catch (ExecutionException e) {// TODO 自动生成的 catch 块e.printStackTrace();}}
}class MyException_one implements Callable<String>{
@Overridepublic String call() throws Exception {// TODO 自动生成的方法存根Thread.sleep(2000);if(true){throw new Exception("抛出异常");}return "one";}}class MyException_two implements Callable<String>{
@Overridepublic String call() throws Exception {// TODO 自动生成的方法存根Thread.sleep(1000);return "two";}}