背景:

如果一个任务由多个子任务组成,子任务全部执行完成后然后由主线程对所有子任务结果进行封装,可以采用如下几种方式:

1、基于Guava ListenableFuture 进行;

2、基于FutureTask 和CountDownLatch进行

3、基于FutureTask进行;

4、基于CompletionService进行

5、基于BlockingQueue进行

说明:

2、3 的区别就是线程池时候每次都新建、shutdown;

4、5 是一个东西

 public static void listenableFuture() {
try {
ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2));
List<ListenableFuture<Integer>> futures = new ArrayList<>();
for (int i = 0; i < 20; i++) {
final ListenableFuture<Integer> future = pool.submit(new CountTask());
futures.add(future);
Futures.addCallback(future, new FutureCallback<Integer>() {
@Override
public void onSuccess(Integer result) {
System.out.println(result);
} @Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
}
System.out.println("submit success");
ListenableFuture<List<Integer>> ret = Futures.successfulAsList(futures);
List<Integer> res = ret.get();
System.out.println(res);
pool.shutdown();
System.out.println("shutdown success");
} catch (Exception e) {
e.printStackTrace();
}
} public static void countDownCount() throws Exception {
int threadNum = 20;
ExecutorService executor = Executors.newCachedThreadPool();
CountDownLatch count = new CountDownLatch(threadNum);
List<FutureTask<Integer>> futureTasks = new ArrayList<>();
for (int i = 0; i < threadNum; i++) {
CountTask task = new CountTask(count);
FutureTask<Integer> futureTask = new FutureTask<>(task);
executor.submit(futureTask);
futureTasks.add(futureTask);
}
// 该动作会阻塞主线程知道各个线程完成任务
count.await();
System.out.println("执行完成");
for (FutureTask<Integer> futureTask : futureTasks) {
Integer ret = futureTask.get();
System.out.println(ret);
}
executor.shutdown();
System.out.println("测试完成");
} public static void futureTaskCount() throws Exception {
int threadNum = 20;
ExecutorService executor = Executors.newCachedThreadPool();
List<FutureTask<Integer>> futureTasks = new ArrayList<>();
for (int i = 0; i < threadNum; i++) {
CountTask task = new CountTask();
FutureTask<Integer> futureTask = new FutureTask<>(task);
executor.submit(futureTask);
futureTasks.add(futureTask);
}
// 关闭线程池,该动作会阻塞主线程知道线程池中线程执行完成
executor.shutdown();
System.out.println("shutdown");
for (FutureTask<Integer> futureTask : futureTasks) {
Integer ret = futureTask.get();
System.out.println(ret);
}
System.out.println("测试完成");
} public static void completionCount() throws Exception {
int threadNum = 20;
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
CompletionService<Integer> pool = new ExecutorCompletionService<Integer>(executor);
for (int i = 0; i < threadNum; i++) {
pool.submit(new CountTask());
}
for (int i = 0; i < threadNum; i++) {
Integer ret = pool.take().get();
System.out.println("输出结果" + ret);
}
System.out.println("测试完成");
executor.shutdown();
} // 使用阻塞容器保存每次Executor处理的结果,在后面进行统一处理
public static void blockingQueueCount() throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
BlockingQueue<Future<Integer>> queue = new LinkedBlockingQueue<Future<Integer>>();
for (int i = 0; i < 10; i++) {
Future<Integer> future = exec.submit(new CountTask());
queue.add(future);
}
int sum = 0;
int queueSize = queue.size();
for (int i = 0; i < queueSize; i++) {
sum += queue.take().get();
}
System.out.println("总数为:" + sum);
exec.shutdown();
}

  

Java 多线程执行的更多相关文章

  1. java 多线程执行过程

    1.分支线程执行 过程: 2.线程运行的状态:五大状态 线程: 从新建状态  就绪状态   运行状态  挂起(阻塞)状态 死亡状态(结束,销毁) 3. 多线程:在同一个时间执行多个任务的操作,现在的软 ...

  2. java多线程执行问题

    class Demo extends Thread{ public Demo(String name){ super(name); } public void run(){ for(int i=0; ...

  3. java 多线程执行时长统计

    ExecutorService——shutdown方法和awaitTermination方法 shutdown方法:平滑的关闭ExecutorService,当此方法被调用时,ExecutorServ ...

  4. java多线程执行时主线程的等待

    1.通过thread.join()方式,注意:如果有多个子线程,需要将全部的线程先start,然后再join.代码示例如下: public class Main {     public static ...

  5. Java多线程--让主线程等待子线程执行完毕

    使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...

  6. Java多线程——<三>简单的线程执行:Executor

    一.概述 按照<Java多线程——<一><二>>中所讲,我们要使用线程,目前都是显示的声明Thread,并调用其start()方法.多线程并行,明显我们需要声明多个 ...

  7. Java 线程和多线程执行过程分析

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  8. JAVA多线程之当一个线程在执行死循环时会影响另外一个线程吗?

    一,问题描述 假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗? 二,示例代码(代码 ...

  9. java 中多线程和锁的使用以及获取多线程执行结果

    多线程一:原生的写法   关键词 implements  实现  Runnable 类 run()  方法 注意点 : 创建类的实例 InterfaceController inter=new Int ...

随机推荐

  1. Nginx的location配置概述【转】

    语法规则: location [=|~|~*|^~] /uri/ { … } = 开头表示精确匹配^~ 开头表示uri以某个常规字符串开头,理解为匹配url路径即可.nginx不对url做编码,因此请 ...

  2. 基于Tcp协议的上传下载

    目录格式: 构建此目录就可随意使用! client端 import socket import sys import os import json import struct sk = socket. ...

  3. Android课程设计第三天帧动画区间动画

    注意:课程设计只为完成任务,不做细节描述~ 点火是帧动画,发射是区间动画,于是 <?xml version="1.0" encoding="utf-8"? ...

  4. 洛谷 P3480 [POI2009]KAM-Pebbles

    https://www.luogu.org/problemnew/solution/P3480 讲不清楚... 首先对原序列做差分:设原序列为a,差分序列为d 那么,每一次按题意在原序列位置i处取走石 ...

  5. 素数+map BestCoder Round #54 (div.2) 1002 The Factor

    题目传送门 题意:给出一个数列,问数列的乘积的一个满足条件的最小因子是什么,没有输出-1.条件是不是素数 分析:官方题解:对于每一个数字,它有用的部分其实只有它的所有质因子(包括相等的).求出所有数的 ...

  6. 题解报告:poj 1738 An old Stone Game(区间dp)

    Description There is an old stone game.At the beginning of the game the player picks n(1<=n<=5 ...

  7. ibatis学习笔记

    步骤: 搭建配置环境:导入相关jar包 配置文件: JDBC连接属性文件 总配置文件 关于每个实体的映射(map.xml)文件 JDBC连接属性文件 jdbc.properties ## mysql ...

  8. RxJava的map方法与flatMap方法

    简单讲,map和flatMap都是来完成Observable构造的数据到Observer接收数据的一个转换,这么说有点绕

  9. (转)Spring提供的CharacterEncoding和OpenSessionInView功能

    http://blog.csdn.net/yerenyuan_pku/article/details/52902282 前面我们以一种更加优雅的方式集成了Spring4.2.5+Hibernate4. ...

  10. 【Android】ListView中EditText焦点问题

    一.描述: 近期一个项目中需要开发一种类似表格的界面来显示和配置参数,Android并无直接类似表格的控件支持,我采用了ListView中布局EditText和TextView来实现,其中TextVi ...