多线程工具之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
复制代码

 

我们可以看到,先执行完的数据就先返回了,实现了我们的预期。

 

posted @   段江涛IT  阅读(514)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
页脚HTML代码
点击右上角即可分享
微信分享提示