java多线程中的CompletionService
来源:互联网 发布:plc编程技巧 编辑:程序博客网 时间:2024/06/04 20:10
在java编程的时候,可能我们会经常遇到多线程的处理问题
有些时候只需要创建子线程让其执行一些逻辑,但是不需要返回数据,那就可以用Thread或者Runnable来实现就行
而有些时候需要创建多个子线程去执行逻辑,并且执行完成后需要拿到返回数据,就可以使用Callable
当我们使用线程池去提交Callable线程任务就可以拿到线程执行返回的Future引用对象,如果不使用CompletionService,那么我们需要自己去创建一个Future的集合,遍历来取值,这样有个不好的地方,如果自己用集合去装Future,那么它的顺序就是根据任务提交的顺序获取子线程返回的值,如果第一个线程执行了10秒而后面的线程最多才执行1秒,那么用这种方式去获取第一个future对象的时候就会被阻塞10秒,若需要多个子线程执行并且特定的线程执行完成之后可以做其他业务,那么这种方式就不适合
如果使用CompletionService去提交任务,返回的Future对象会根据执行的时间将执行最快的子线程的结果最先返回
不使用CompletionService就相当于:
线程池 + Callable + 阻塞队列
使用CompletionService就相当于:
线程池 + CompletionService(Callable + 阻塞队列 + 时间优先返回)
下面是一个测试:
这里定义一个Callable:
package cn.lijie.thread;import java.util.concurrent.Callable;public class MyCallable implements Callable<String> { private int sleep; public MyCallable(int sleep) { this.sleep = sleep; } public String call() throws Exception { Thread.sleep(sleep); return Thread.currentThread().getName() + ":睡眠了" + sleep + "秒"; }}
如果不使用CompletionService:
package cn.lijie.thread;import java.util.concurrent.*;public class MainOne { public static void main(String[] args) throws Exception { //创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(200); //创建阻塞队列 BlockingQueue<Future<String>> blockingQueue = new LinkedBlockingQueue<Future<String>>(); for (int i = 10; i > 0; i--) { Future<String> future = executorService.submit(new MyCallable(i * 500)); blockingQueue.add(future); } for (int i = 1; i <= 10; i++) { Future<String> take = blockingQueue.take(); String res = take.get(); System.out.println("MainOwo查看执行情况:" + res); } executorService.shutdown(); }}
执行的结果如下:
如果使用CompletionService:
package cn.lijie.thread;import java.util.concurrent.*;public class MainTwo { public static void main(String[] args) throws Exception { //创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(200); //创建CompletionService CompletionService<String> completionService = new ExecutorCompletionService<String>(executorService); for (int i = 10; i > 0; i--) { completionService.submit(new MyCallable(i * 500)); } for (int i = 1; i <= 10; i++) { Future<String> take = completionService.take(); String res = take.get(); System.out.println("MainTwo查看执行情况:" + res); } executorService.shutdown(); }}
执行结果如下:
可以通过上面的执行结果对比,使用了CompletionService 就会先获取到最快执行完成的子线程返回值,而不使用CompletionService就按照提交顺序阻塞获取
- java多线程中的CompletionService
- java中的多线程包---CompletionService Executor + BlockingQueue
- Java多线程-CompletionService
- Java多线程-Executor框架:CompletionService
- Java多线程-Executor框架:CompletionService
- Java多线程--CompletionService的使用
- 多线程-CompletionService
- java多线程 之 CompletionService与ExecutorCompletionService
- JAVA多线程—CompletionService的使用介绍
- java-CompletionService
- java高并发之CompletionService优化多线程并发
- Java 多线程中关于 ExecutorService 和 CompletionService的讨论
- 多线程之CompletionService使用
- java并发:ExecutorServiec中的CompletionService和invokeAll的使用
- java concurrent之CompletionService
- Java之CompletionService
- Java线程之CompletionService
- JAVA CallableAndFuture CompletionService
- 对Setup time 和Hold time计算关系的理解
- 结合redis设计与实现的redis源码学习-14-事件(ae.c/ae_epoll.c)
- C# byte 和 char 转化
- 自己写的1050螺旋矩阵(25)
- 文章标题
- java多线程中的CompletionService
- 模拟角频率和数字角频率的关系
- redis主从复制
- IOS开发中NSRunloop跟NSTimer的问题
- NGUI减少Drawcall
- 傅立叶变换
- Javascript removeChild()不能删除全部子节点的解决办法
- MIPS汇编语言指令类型
- 共享内存