java高级---->Thread之CompletionService的使用
CompletionService的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离开来进行处理。今天我们通过实例来学习一下CompletionService的用法。
CompletionService的简单使用
使用submit()方法执行任务,使用take取得已完成的任务,并按照完成这些任务的时间顺序处理它们的结果。
一、CompletionService的submit方法
public class CompletionServiceTest {
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(5);
CompletionService<String> completionService = new ExecutorCompletionService<String>(service);
for (int i = 0; i < 5; i++) {
completionService.submit(new ReturnAfterSleepCallable(i));
}
System.out.println("after submit");
for (int i = 0; i < 5; i++) {
System.out.println("result: " + completionService.take().get()); // 这个方法是阻塞的
}
System.out.println("after get");
service.shutdown();
}
private static class ReturnAfterSleepCallable implements Callable<String> {
int sleep;
public ReturnAfterSleepCallable(int sleep) {
this.sleep = sleep;
}
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(sleep);
return System.currentTimeMillis() + ",sleep=" + String.valueOf(sleep);
}
}
}
运行的结果如下:
after submit
result: ,sleep=
result: ,sleep=
result: ,sleep=
result: ,sleep=
result: ,sleep=
after get
官方文档上的说明:
Submits a value-returning task for execution and returns a Future representing the pending results of the task. Upon completion, this task may be taken or polled.
二、使用CompletionService的take方法
take()方法取得最先完成任务的Future对象,谁执行时间最短谁最先返回。
package com.linux.thread; import java.util.Random;
import java.util.concurrent.*; public class RunMain1 {
public static void main(String[] args) {
try {
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
for (int i = 0; i < 10; i++) {
completionService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
int sleepValue = new Random().nextInt(5);
System.out.println("sleep = " + sleepValue + ", name: " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(sleepValue);
return "huhx: " + sleepValue + ", " + Thread.currentThread().getName();
}
});
}
for (int i = 0; i < 10; i++) {
System.out.println(completionService.take().get());
}
executorService.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
一次的运行结果如下:
sleep = , name: pool--thread-
sleep = , name: pool--thread-
sleep = , name: pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
sleep = , name: pool--thread-
sleep = , name: pool--thread-
sleep = , name: pool--thread-
sleep = , name: pool--thread-
sleep = , name: pool--thread-
huhx: , pool--thread-
sleep = , name: pool--thread-
sleep = , name: pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
huhx: , pool--thread-
官方文档上的说明:
Retrieves and removes the Future representing the next completed task, waiting if none are yet present.
三、使用CompletionService的poll方法
方法poll的作用是获取并移除表示下一个已完成任务的Future,如果不存在这样的任务,则返回null,方法poll是无阻塞的。
package com.linux.thread;
import java.util.concurrent.*;
public class RunMain2 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
CompletionService<String> service = new ExecutorCompletionService<String>(executorService);
service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(3);
System.out.println("3 seconds pass.");
return "3秒";
}
});
System.out.println(service.poll());
executorService.shutdown();
}
}
运行的结果如下:
null
seconds pass.
官方文档上的说明:
Retrieves and removes the Future representing the next completed task or null if none are present.
友情链接
java高级---->Thread之CompletionService的使用的更多相关文章
- java高级---->Thread之ScheduledExecutorService的使用
ScheduledExecutorService的主要作用就是可以将定时任务与线程池功能结合使用.今天我们来学习一下ScheduledExecutorService的用法.我们都太渺小了,那么容易便湮 ...
- java高级---->Thread之ExecutorService的使用
今天我们通过实例来学习一下ExecutorService的用法.我徒然学会了抗拒热闹,却还来不及透悟真正的冷清. ExecutorService的简单实例 一.ExecutorService的简单使用 ...
- java高级---->Thread之Phaser的使用
Phaser提供了动态增parties计数,这点比CyclicBarrier类操作parties更加方便.它是jdk1.7新增的类,今天我们就来学习一下它的用法.尘埃落定之后,回忆别来挑拨. Phas ...
- java高级---->Thread之CyclicBarrier的使用
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).今天我们就学习一下CyclicBarrier的用法. Cycl ...
- java高级---->Thread之BlockingQueue的使用
今天我们通过实例来学习一下BlockingQueue的用法.梦想,可以天花乱坠,理想,是我们一步一个脚印踩出来的坎坷道路. BlockingQueue的实例 官方文档上的对于BlockingQueue ...
- java高级---->Thread之Exchanger的使用
Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据.今天我们就通过实例来学习一下Exchanger的用法. Exchanger的简单实例 Exchanger是 ...
- java高级---->Thread之FutureTask的使用
FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行.今天我们通过实例来学习一下FutureTask的 ...
- java高级---->Thread之Condition的使用
Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...
- java高级---->Thread之CountDownLatch的使用
CountDownLatch是JDK 5+里面闭锁的一个实现,允许一个或者多个线程等待某个事件的发生.今天我们通过一些实例来学习一下它的用法. CountDownLatch的简单使用 CountDow ...
随机推荐
- [shell]shell脚本传入不固定参数的写法,如--help等
最近在调试一个wifi模块,需要传一些不固定的参数,一下一个参数解析的函数可以搞定这个事情,里面内容好多部分是从一个example中剽窃而来(窃喜) #!/bin/bash # writen by a ...
- 分别通过【buildpath】和【lib】倒入JAR包有什么不同
我们可以通过java虚拟机的类加载器来理解.通过buildpath设置(或添加)程序使用jar包的classpath.Java虚拟机是根据Java ClassLoader(类加载器)决定如何,到那里去 ...
- skynet1.0阅读笔记_skynet的启动
首先看skynet的启动,函数入口在 skynet_main.c 的main(),其中最重要的是: skynet_start(&config); 在skynet_start中做了两个启动: / ...
- 成员函数后面加const,没有const,以及使用的区别
函数后面加const 编译器会自动给每一个函数加一个this指针.在一个类的函数后面加上const后,就表明这个函数是不能改变类的成员变量的(加了mutable修饰的除外,后面有讲).实际上,也就是对 ...
- 第三百零八节,Django框架,models.py模块,数据库操作——链表结构,一对多、一对一、多对多
第三百零八节,Django框架,models.py模块,数据库操作——链表结构,一对多.一对一.多对多 链表操作 链表,就是一张表的外键字段,连接另外一张表的主键字段 一对多 models.Forei ...
- Java基础-JDBC访问数据库
基本步骤: 加载数据库驱动 建立连接 创建SQL语句 执行SQL语句 处理执行结果 释放资源 代码示例: import java.sql.Connection; import java.sql.Dri ...
- 清理SYSAUX表空间的WRH$_LATCH_CHILDREN表
周六 被突然起来的短信 轰醒. 一看有63条短信. 都是来之与监控中的.有关表空间大小超过某个警戒值. 发现 SYSAUX表空间超过了15GB 通过以下代码查看SYSAUX表空间的功能占用情况 SEL ...
- linux nfs
linux(十四)之linux NFS服务管理 学到这里差不多就结束了linux的基础学习了,其实linux的内容并不难,我们要经常的反复的去操作它,多多和它去联络感情才能很好的掌握这个linux. ...
- 上传文件到 Sharepoint 的文档库中和下载 Sharepoint 的文档库的文件到客户端
文件操作应用场景: 如果你的.NET项目是运行在SharePoint服务器上的,你可以直接使用SharePoint服务器端对象模型,用SPFileCollection.Add方法 http://msd ...
- 调用外部 DLL 中的函数(2. 晚绑定)
, b, t, );end; procedure TForm1.FormDestroy(Sender: TObject);begin FreeLibrary(inst); {记得释放}end; e ...