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的使用的更多相关文章

  1. java高级---->Thread之ScheduledExecutorService的使用

    ScheduledExecutorService的主要作用就是可以将定时任务与线程池功能结合使用.今天我们来学习一下ScheduledExecutorService的用法.我们都太渺小了,那么容易便湮 ...

  2. java高级---->Thread之ExecutorService的使用

    今天我们通过实例来学习一下ExecutorService的用法.我徒然学会了抗拒热闹,却还来不及透悟真正的冷清. ExecutorService的简单实例 一.ExecutorService的简单使用 ...

  3. java高级---->Thread之Phaser的使用

    Phaser提供了动态增parties计数,这点比CyclicBarrier类操作parties更加方便.它是jdk1.7新增的类,今天我们就来学习一下它的用法.尘埃落定之后,回忆别来挑拨. Phas ...

  4. java高级---->Thread之CyclicBarrier的使用

    CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).今天我们就学习一下CyclicBarrier的用法. Cycl ...

  5. java高级---->Thread之BlockingQueue的使用

    今天我们通过实例来学习一下BlockingQueue的用法.梦想,可以天花乱坠,理想,是我们一步一个脚印踩出来的坎坷道路. BlockingQueue的实例 官方文档上的对于BlockingQueue ...

  6. java高级---->Thread之Exchanger的使用

    Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据.今天我们就通过实例来学习一下Exchanger的用法. Exchanger的简单实例 Exchanger是 ...

  7. java高级---->Thread之FutureTask的使用

    FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行.今天我们通过实例来学习一下FutureTask的 ...

  8. java高级---->Thread之Condition的使用

    Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...

  9. java高级---->Thread之CountDownLatch的使用

    CountDownLatch是JDK 5+里面闭锁的一个实现,允许一个或者多个线程等待某个事件的发生.今天我们通过一些实例来学习一下它的用法. CountDownLatch的简单使用 CountDow ...

随机推荐

  1. c# 终止线程

    最近在弄一个等待窗口,使用了线程去调用form.在结束线程这边碰到了些问题.调用: thread.Abort();thread.Join();老被ThreadAbortException异常抛出困扰. ...

  2. LAN8710A/LAN8710Ai datasheet 记录

    因为产品的双网口出现了问题,而且是AM335x 内部驱动,难度比较大,现从PHY 端开始分析相关原理,找到双网口不能使用的原因. 此篇是记录一些有关LAN8710A 这个PHY的一些特性. 各个功能模 ...

  3. sed: 1: “…”: invalid command code on Mac OS

    昨天因为项目中有很多文件的同一个变量需要批量替换成另一个,想用sed做这个.Linux 这样其实就可以了 ~# sed -i “s/string_old/string_new/g” grep -rl ...

  4. Bit operator: Left shift and Right shift (Signed or unsigned? )

    No matter left shift or right shift, the result's sign should always be the same as its left operand ...

  5. 查看nginx cache命中率

    一.在http header上增加命中显示 nginx提供了$upstream_cache_status这个变量来显示缓存的状态,我们可以在配置中添加一个http头来显示这一状态,达到类似squid的 ...

  6. FroalaEditor使用方法汇总

    最近在整个移动端富文本编辑器.写完后,在安卓端表现良好,在苹果端测试让我直吐血.开始在网上找了一圈,也没发现自己中意的那款. 今天无意中发现了FroalaEditor,经过在移动端测试一番,表现的好的 ...

  7. Android Studio编译错误:Unexpected lock protocol found in lock file. Expected 3, found 0.

    如果不小心手动修改了.gradle文件夹中的内容,那么再打开之前编译成功的工程时,会出现类似下面的错误: Gradle app neame project refresh failed: Unexpe ...

  8. (转)x264参数中文详解(X264 Settings)

    0 解释x264命令可选项的用途和使用方法.同执行 x264 --fullhelp 显示顺序.本文主要翻译:mewiki.project357.com/wiki/X264_Settings,同时参考d ...

  9. erlang的小知识,未分类。

    erlang:module_loaded(module):检测模块是否已加载:

  10. oracle的varchar2和clob类型在hibernate中使用

    1.在oracle中 varchar2的最大长度为4000 bytes,即varchar2(4000),最多能储存2000个汉子或4000位的数字字母.当储存值超过时可以使用clob(Characte ...