【Java并发核心六】CompletionService
CompletionService 接口的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样就可以将执行任务与处理任务分离开。
CompletionService 仅有一个实现类 ExecutorCompletionService,需要依赖Executor对象,其大部分实现是使用线程池 ThreadPoolExecutor实现的。
构造方法有两个
// Linkedblockingqueue作为任务完成队列 ExecutorCompletionService(Executor executor) // 将所提供队列作为任务完成队列 ExecutorCompletionService(Executor executor, BlockingQueue<Future<V>> completionQueue)
使用实例:
final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); CompletionService<String> csv = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(10)); // 此线程池运行5个线程 for (int i = 0; i < 5; i++) { final int index = i; csv.submit(new Callable<String>() { @Override public String call() throws Exception { System.out.println("Thread-" + index + "-begin-" + sf.format(new Date())); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread-" + index + "-end-" + sf.format(new Date())); return "index-" + index; } }); } try { Future<String> f = csv.poll(); // poll方法 返回的Future可能为 null,因为poll 是非阻塞执行的 if (f != null) { System.out.println(f.get()); } else { System.out.println("使用poll 获取到的Future为 null"); } } catch (Exception e1) { e1.printStackTrace(); } for (int i = 0; i < 5; i++) { try { // csv.take() 返回的是 最先完成任务的 Future 对象,take 方法时阻塞执行的 System.out.println(csv.take().get()); } catch (Exception e) { e.printStackTrace(); } }
运行结果:
这里有两个方法:
take() 返回的是 最先完成任务的 Future 对象,take() 方法时阻塞执行的
pool() 返回的Future可能为 null,因为poll() 是非阻塞执行的。
未来的自己若是充满勇气,一定会感谢今日的孤独。