completionService的使用
来源:互联网 发布:淘宝导航栏代码生成器 编辑:程序博客网 时间:2024/06/05 22:42
CompletionService
接口CompletionService 的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与从处理任务分离开来进行处理。使用submit执行任务,使用take取得已完成的任务,并按照完成这些任务的时间处理它们的结果。
接口CompletionService仅有一个实现类 ExecutorCompletionService,构造方法
public ExecutorCompletionService(Executor executor)public ExecutorCompletionService(Executor executor, BlockingQueue<Future<V>> completionQueue)
需要依赖于Executor对象,大部分的实现也就是使用线程池ThreadPoolExecutor对象。
Future具有阻塞同步性,接口CompletionService可以解决解决这个问题
public class MyCallable implements Callable<String> { private String userName; private long sleepValue; public MyCallable(String userName, long sleepValue) { this.userName = userName; this.sleepValue = sleepValue; } @Override public String call() throws Exception { Thread.sleep(sleepValue); return "return " + userName; }}public class RunTest { public static void main(String[] args){ MyCallable callable1 = new MyCallable("username1", 5000); MyCallable callable2 = new MyCallable("username2", 4000); MyCallable callable3 = new MyCallable("username3", 3000); MyCallable callable4 = new MyCallable("username4", 2000); MyCallable callable5 = new MyCallable("username5", 1000); List<Callable> callableList = new ArrayList<Callable>(); callableList.add(callable1); callableList.add(callable2); callableList.add(callable3); callableList.add(callable4); callableList.add(callable5); ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); ExecutorCompletionService<Object> csRef = new ExecutorCompletionService<>(executor); for(int i=0;i<5;i++){ csRef.submit(callableList.get(i)); } try { for(int i=0;i<5;i++){ System.out.println("wait for print " + (i+1) + " result"); System.out.println(csRef.take().get()); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executor.shutdown(); }结果wait for print 1 resultreturn username5wait for print 2 resultreturn username4wait for print 3 resultreturn username3wait for print 4 resultreturn username2wait for print 5 resultreturn username1
使用CompletionService接口后,哪个任务先执行完,哪个任务的返回值就先打印。如果当前任务没有执行完,则csRef.take().get()方法还是阻塞。
take()
方法take()取得最先完成任务的Future对象,谁执行时间最短谁最先返回。
public class RunTest { public static void main(String[] args){ ExecutorService executorService = Executors.newCachedThreadPool(); ExecutorCompletionService<String> csRef = new ExecutorCompletionService<String>(executorService); for(int i=0;i<10;i++){ csRef.submit(new Callable<String>() { @Override public String call() throws Exception { long sleepValue = (int)(Math.random()*1000); System.out.println("sleep="+sleepValue+" "+ Thread.currentThread().getName()); Thread.sleep(sleepValue); return "test " + Thread.currentThread().getName(); } }); } try { for(int i=0;i<10;i++){ System.out.println(csRef.take().get()); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
poll()
poll()获取并移除已完成任务的Future,非阻塞,不存在已完成任务则返回null
public class RunTest { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); ExecutorCompletionService<String> csRef = new ExecutorCompletionService<String>(executorService); for (int i = 0; i < 10; i++) { csRef.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(3000); return "test " + Thread.currentThread().getName(); } }); } System.out.println(csRef.poll()); Thread.sleep(4000); System.out.println(csRef.poll().get()); }}结果nulltest pool-1-thread-1
统计程序运行时间
long start = System.currentTimeMillis();long end = System.currentTimeMillis();(end-start)/1000 秒
poll()超时处理
poll(long timeout, TimeUnit unit)
public class RunTest { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); ExecutorCompletionService<String> csRef = new ExecutorCompletionService<String>(executorService); MyCallable callableA = new MyCallable("username1",2000); MyCallable callableB = new MyCallable("username2",2000); long start = System.currentTimeMillis(); csRef.submit(callableA); csRef.submit(callableB); for(int i=0;i<2;i++){ System.out.println("zzz "+ csRef.poll(6,TimeUnit.SECONDS).get()); } System.out.println("main end!"); long end = System.currentTimeMillis(); // 关闭线程池确定任务结束 executorService.shutdown(); executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); System.out.println("time is " + (end-start)/1000); }}结果zzz return username2zzz return username1main end!time is 2
poll(long timeout,TimeUnit unit)方法是阻塞的
public class RunTest { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); ExecutorCompletionService<String> csRef = new ExecutorCompletionService<String>(executorService); MyCallable callableA = new MyCallable("username1",4000); MyCallable callableB = new MyCallable("username2",4000); long start = System.currentTimeMillis(); csRef.submit(callableA); csRef.submit(callableB); // poll方法在接下来的6秒之内会轮询,直到有数据返回继续向下执行,或者超时向下执行 System.out.println("zzz "+ csRef.poll(6,TimeUnit.SECONDS).get()); // 从结果可以看出,poll(long timeout,TimeUnit unit)是方法阻塞的 System.out.println("hello hello "); System.out.println("zzz "+ csRef.poll(2,TimeUnit.SECONDS).get()); long end = System.currentTimeMillis(); executorService.shutdown(); executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); System.out.println("main end!"); System.out.println("time is " + (end-start)/1000); }}结果zzz return username1hello hello zzz return username2main end!time is 4
某一个任务失败不会影响这个任务执行之前成功的任务,却会导致之后的任务失败。
Future submit(Runnable task,V result)方法
public class RunTest { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); ExecutorCompletionService<UserInfo> csRef = new ExecutorCompletionService<UserInfo>(executorService); UserInfo userInfo = new UserInfo(); userInfo.setUsername("one"); System.out.println("before " + userInfo.getUsername()); // 注:UserIno类的run方法会抛出异常 MyRunnable myRunnable = new MyRunnable(userInfo); Future<UserInfo> future = csRef.submit(myRunnable, userInfo); System.out.println("after " + future.get().getUsername()); }}结果before onerunning ...after usernameValue
0 0
- completionService的使用
- CompletionService的介绍和使用
- CompletionService的介绍和使用
- Java多线程--CompletionService的使用
- CompletionService使用
- JAVA多线程—CompletionService的使用介绍
- 使用CompletionService批处理任务
- 多线程之CompletionService使用
- 使用CompletionService批处理任务
- 使用CompletionService批处理任务
- 【Java】CompletionService 使用
- Callable和CompletionService的使用,多任务返回值。
- java并发:ExecutorServiec中的CompletionService和invokeAll的使用
- Java并发编程核心方法与框架-CompletionService的使用
- CompletionService和ExecutorCompletionService的好处和使用场景
- 理解java的CompletionService
- CompletionService
- CompletionService
- cassandra cql
- 深入理解CSS3 Animation 帧动画(step详解)
- Hibernate关联遇敌:一对一主键关联
- Jeecms网站直接访问html静态页面
- 找的c++基础知识
- completionService的使用
- 复合句 - 状语从句
- Cocospod 私有库
- linux基础学习总结03
- ArrayList
- z-wave_device_class_specification中对doorbell门铃实现功能的规定
- c语言==常见问答细节点(19)
- 使用benchmark.js进行前端代码基准测试
- [bzoj3100]排列