【并发编程】- ExecutorCompletionService使用poll()方法移除已完成的任务

171 阅读1分钟

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

ExecutorCompletionService使用poll()方法移除已完成的任务

方法poll()的作用是获取并移除表示下一个已完成任务的Future,如果不存在的任务,那么返回null,poll()方法无阻塞的特性。

运行类执行代码如下:

@Slf4j
public class CompletionServicePollRun {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ExecutorCompletionService completionService = new ExecutorCompletionService(executorService);
        for (int i = 0; i < 1; i++) {
            completionService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(5000);
                    log.info("线程休眠5秒后...");
                    return "休眠时间:5s";
                }
            });
        }
        for (int i = 0; i < 1 ; i++) {
            log.info("移除已完成的任务结果:{}",completionService.poll());
        }
    }
}

运行结果如下:

[main] INFO com.ozx.concurrentprogram.executor.controller.CompletionServicePollRun - 移除已完成的任务结果:null [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.controller.CompletionServicePollRun - 线程休眠5秒后...

从运行结果看出poll()方法返回的Future为null,原因是当前没有任何已完成的任务可以被移除,所以返回为null,因此证明了poll()方法和take()方法不一样,它不具有阻塞特性。

使用poll(long timeout,TimeUnit unit)方法

方法Future poll(long timeout,TimeUnit unit)的作用是等待执行的timeout时间,在timeout时间之内获取返回值时立即向下继续执行,如果超时也立即向下继续执行。

线程执行代码如下:

public class PollFirstCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(5000);
        System.out.println(super.getClass().getName() +"线程执行任务时间:"+System.currentTimeMillis());
        return super.getClass().getName();
    }
}
public class PollSecondCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(3000);
        System.out.println(super.getClass().getName() + "线程执行任务时间:" + System.currentTimeMillis());
        return super.getClass().getName();
    }
}

运行类执行代码如下:

public class SecondPollRun {
    public static void main(String[] args) {
        PollFirstCallable pollFirstCallable = new PollFirstCallable();
        PollSecondCallable pollSecondCallable = new PollSecondCallable();

        ExecutorService executorService = Executors.newCachedThreadPool();
        ExecutorCompletionService completionService = new ExecutorCompletionService(executorService);
        completionService.submit(pollFirstCallable);
        completionService.submit(pollSecondCallable);

        for (int i = 0; i < 2; i++) {
            System.out.println("移除已完成任务的结果:"+completionService.poll());
        }
        System.out.println("主线程输出结果完成!");
    }
}

运行结果如下:

移除已完成任务的结果:null

移除已完成任务的结果:null

主线程输出结果完成!

com.ozx.concurrentprogram.executor.service.PollSecondCallable线程执行任务时间:1660274125962

com.ozx.concurrentprogram.executor.service.PollFirstCallable线程执行任务时间:1660274125964

从运行结果看出移除已完成任务两次结果都是null,因为两个任务都在休眠中。