【并发编程】- ExecutorCompletionService使用take()方法获取最先执行完的任务

95 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

ExecutorCompletionService使用take()方法获取最先执行完的任务

运行类执行代码如下:

@Slf4j
public class CompletionServiceTakeRun {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ExecutorCompletionService completionService = new ExecutorCompletionService(executorService);
        for (int i = 0; i < 10 ; i++) {
            completionService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    long sleepTime =(int)((Math.random()) * 1000);
                    log.info("线程名:{},休眠时间:{}",Thread.currentThread().getName(),sleepTime);
                    Thread.sleep(sleepTime);
                    return "休眠时间: "+sleepTime+"线程名: "+Thread.currentThread().getName();
                }
            });
        }
        for (int i = 0; i < 10 ; i++) {
            try {
                log.info("获取线程返回值:{}",completionService.take().get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果如下:

[pool-1-thread-8] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-8,休眠时间:180

[pool-1-thread-4] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-4,休眠时间:562

[pool-1-thread-6] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-6,休眠时间:905

[pool-1-thread-7] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-7,休眠时间:454

[pool-1-thread-9] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-9,休眠时间:921

[pool-1-thread-3] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-3,休眠时间:411

[pool-1-thread-10] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-10,休眠时间:259

[pool-1-thread-2] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-2,休眠时间:166

[pool-1-thread-5] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-5,休眠时间:188

[pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 线程名:pool-1-thread-1,休眠时间:829

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 166线程名: pool-1-thread-2

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 180线程名: pool-1-thread-8

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 188线程名: pool-1-thread-5

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 259线程名: pool-1-thread-10

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 411线程名: pool-1-thread-3

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 454线程名: pool-1-thread-7

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 562线程名: pool-1-thread-4

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 829线程名: pool-1-thread-1

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 905线程名: pool-1-thread-6

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServiceTakeRun - 获取线程返回值:休眠时间: 921线程名: pool-1-thread-9

从运行结果看出ExecutorCompletionService的take()方法是按任务执行的速度,从执行时间短到执行时间长的顺序获取Future对象,所以输出休眠时间从小到大排列。