多线程工具之CompletionService
这里涉及到Java的多线程并发知识,以及线程池相关的知识。就不在此说明了。具体说说CompletionService的应用场景和使用方法。
比如我们有10个线程需要丢到线程池里面去执行,然后把10个线程的执行结果返回回来处理。如果没有使用CompletionService,我们的实现方式如下。首先创建线程类Worker
private static class Worker implements Callable<Integer> { private int time; public Worker(int time) { this.time = time; } @Override public Integer call() throws Exception { Thread.sleep(time); return time; } }
因为我这里是写到主方法类里面的,所以是private static。
主方法实现代码如下:
private static void main(String[] args) throws InterruptedException, ExecutionException { // 定义线程池 ExecutorService pool = Executors.newFixedThreadPool(10); // 定义存储线程的集合 BlockingQueue<Future<Integer>> tasks = new LinkedBlockingQueue<>(); for (int i = 0; i < 10; i++) { Worker work = null; if (i % 2 == 0) { work = new Worker(i * 100); } else { work = new Worker(i * 50); } tasks.add(pool.submit(work)); } for (int i = 0; i < 10; i++) { int m = tasks.take().get(); System.out.println("result=" + m); } pool.shutdown(); }
打印出的结果如下:
result=0 result=50 result=200 result=150 result=400 result=250 result=600 result=350 result=800 result=450
可以看到,无论线程谁先执行完,最后都是先放进线程池的先取出结果。而如果我们想要哪个线程先执行完就先返回结果怎么办呢。这时候就需要CompletionService了。具体代码如下,只有主方法有变化:
private static void main(String[] args) throws InterruptedException, ExecutionException { // 定义线程池 ExecutorService pool = Executors.newFixedThreadPool(10); //定义ExecutorService CompletionService<Integer> service=new ExecutorCompletionService<>(pool); for (int i = 0; i < 10; i++) { Worker work = null; if (i % 2 == 0) { work = new Worker(i * 100); } else { work = new Worker(i * 50); } service.submit(work); } for (int i = 0; i < 10; i++) { int m = service.take().get(); System.out.println("result=" + m); } pool.shutdown(); }
执行结果如下:
result=0 result=50 result=150 result=200 result=250 result=350 result=400 result=450 result=600 result=800
我们可以看到,先执行完的数据就先返回了,实现了我们的预期。