ExecutorCompletionService 管理线程池处理任务的返回结果

在我们日常使用线程池的时候,经常会有需要获得线程处理结果的时候。此时我们通常有两种做法。

1. 使用并发容器将callable.call() 的返回Future存储起来。然后使用一个消费者线程去遍历这个并发容器,调用Future.isDone()去判断各个任务是否处理完毕。然后再处理响应的业务。

复制代码

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;

public class ExecutorResultManager {

    public static void main(String[] args) {
        // 队列
        BlockingQueue<Future<String>> futures = new LinkedBlockingQueue<>();
        
        // 生产者
        new Thread() {
            @Override
            public void run() {
                ExecutorService pool = Executors.newCachedThreadPool();
                
                for (int i=0; i< 10; i++) {
                    int index = i;
                    Future<String> submit = pool.submit(new Callable<String>() {
                        @Override
                        public String call() throws Exception {
                            return "task done" + index;
                        }
                    });
                    try {
                        futures.put(submit);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        
        

        // 消费者
        new Thread() {
            @Override
            public void run() {
                while(true) {
                    for (Future<String> future : futures) {
                        if(future.isDone()) {
                            // 处理业务
                            // .............
                            
                            
                        };
                    }
                }
            }
        }.start();
    }

}

复制代码

2. 使用jdk 自带线程池结果管理器:ExecutorCompletionService。它将BlockingQueue 和Executor 封装起来。然后使用ExecutorCompletionService.submit()方法提交任务。

import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorCompletionServiceManager {

    public static void main(String[] args) {

        ExecutorCompletionService<String> service = new ExecutorCompletionService<String>(
                Executors.newCachedThreadPool());

        // 生产者
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    int index = i;
                    service.submit(new Callable<String>() {
                        @Override
                        public String call() throws Exception {
                            return "task done" + index;
                        }
                    });
                }
            }
        }.start();
        

        // 消费者
        new Thread() {
            @Override
            public void run() {
                try {
                    Future<String> take = service.take();
                    // do some thing........
                    
                    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }
}

另外一个例子:

public class Application {
    
    public static void main(String[] args) throws Exception {
        //SpringApplication.run(Application.class, args);
        Application application = new Application();
        
        for(int i=0; i<10000; i++){
            Application.Sub sub = application.new Sub();
            boolean value = sub.test();
            System.out.println("end="+value);
        }
    }
    class Sub{
        public Boolean test() throws Exception{
            ExecutorService service = Executors.newFixedThreadPool(2);
            CompletionService<Boolean> completionService = new ExecutorCompletionService<Boolean>(service);
            
            try {
                for(int i=0; i<1; i++){
                    completionService.submit(new Callable<Boolean>() {
                        @Override
                        public Boolean call() throws Exception {
                            Thread.sleep(100);
                            //throw new NullPointerException("lalalalala");
                            return true;
                        }
                    });
                }
                
                for(int i=0; i<1; i++){
                    System.out.println(completionService.take().get());
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
                return false;
            } finally {
                service.shutdown();
            }
            
            return true;
        }
    }
    
}
 

猜你喜欢

转载自blog.csdn.net/boguesfei/article/details/81711971