• 多线程工具之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

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

  • 相关阅读:
    Java笔记6之三目运算符
    java笔记5之逻辑运算符以及&&与&的区别
    SAP CRM OData模型里的addressable为true的含义
    SAP CRM OData multiple origin Composition的测试
    重构老系统遗留代码的一些方法学习笔记
    SAP CRM系统里的附件存储逻辑
    如何用Postman创建SAP CRM的Opportunity业务数据
    另一种使用SAP SAT事务码对通过浏览器启动的应用的性能测量和分析方式
    SAP Hybris Commerce,CRM和C4C的登录语言选择
    SAP Hybris Commerce的页面路由实现
  • 原文地址:https://www.cnblogs.com/duanjt/p/9815220.html
Copyright © 2020-2023  润新知