携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
ExecutorCompletionService类与异常(三)
修改第一个任务和第二个任务执行顺序
修改运行类执行代码如下:
public class ExceptionCallableRun {
public static void main(String[] args) {
ExceptionFirstCallable firstCallable = new ExceptionFirstCallable();
ExceptionSecondCallable secondCallable = new ExceptionSecondCallable();
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorCompletionService executorCompletionService = new ExecutorCompletionService(executorService);
executorCompletionService.submit(secondCallable);
executorCompletionService.submit(firstCallable);
for (int i = 0; i < 2 ; i++) {
System.out.println("移除已完成任务:"+executorCompletionService.poll());
}
try {
Thread.sleep(8000);
System.out.println("第一个线程: "+executorCompletionService.poll().get());
System.out.println("第二个线程: "+executorCompletionService.poll().get());
System.out.println("主线程结束!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果如下:
移除已完成任务:null 移除已完成任务:null com.ozx.concurrentprogram.executor.service.ExceptionSecondCallable 线程执行开始时间:1660726435173 Exception in thread "main" java.lang.NullPointerException at com.ozx.concurrentprogram.executor.controller.ExceptionCallableRun.main(ExceptionCallableRun.java:39) com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable 线程执行开始时间:1660726445178 com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable 线程执行结束时间:1660726449190
丛运行结果看来第二个任务先执行,第二个任务执行发生异常,调用poll().get()方法直接抛出异常信息,第一个任务执行后并未输出任务的返回值。
CompletionService的submit(Runnable runnable,V result)的使用
实体类代码如下:
@Data
public class User {
private String username;
private String password;
}
线程执行代码如下:
public class ThirdRunnable implements Runnable {
private User user;
public ThirdRunnable(User user){
super();
this.user=user;
}
@Override
public void run() {
user.setUsername("Gxin");
user.setPassword("20220819");
System.out.println(super.getClass().getName()+"运行了");
}
}
运行类执行代码如下:
public class CompletionServiceRun {
public static void main(String[] args) {
User user = new User();
ThirdRunnable thirdRunnable = new ThirdRunnable(user);
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorCompletionService completionService = new ExecutorCompletionService(executorService);
Future<User> future = completionService.submit(thirdRunnable, user);
try {
System.out.println("账号:"+future.get().getUsername() +" 密码:"+future.get().getPassword());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果如下:
com.ozx.concurrentprogram.executor.service.ThirdRunnable运行了
账号:Gxin 密码:20220819
接口CompletionService完全可以避免FutureTask类的阻塞的缺点,可更加有效处理Future的返回结果,就是说哪个任务先执行完,CompletionService就会先获取这个任务的返回值再接着往下处理。