1.

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList; public class CompletableFutureTest {
static final UserFeatureable[] UserFeatures = {new GetCareerUserFeature(), new GetTradeUserFeature(), new
GetVipLevelUserFeature()}; public static void main(String[] args) {
int id = 10001;
List<UserFeatureable> userFeatures = Arrays.asList(UserFeatures);
long startTime = System.currentTimeMillis();
String result = userFeatures.parallelStream().map(p -> p.getKey() + ":" + p.getValue(id)).collect(joining(","));
long endTime = System.currentTimeMillis();
System.out.println(String.format("parallelStream消耗时间:%d,返回结果:%s", (endTime - startTime), result)); startTime = System.currentTimeMillis();
List<Future<String>> futureList = userFeatures.stream().map(
p -> CompletableFuture.supplyAsync(() -> p.getKey() + ":" + p.getValue(id)))
.collect(toList());
result = futureList.stream().map(p->getVal(p,"")).collect(joining(","));
endTime = System.currentTimeMillis();
System.out.println(String.format("CompletableFuture的默认的ForkJoin线程池消耗时间:%d,返回结果:%s", (endTime - startTime),
result)); //当userFeature越多,使用自定义线程池更有利
startTime = System.currentTimeMillis();
futureList = userFeatures.stream().map(
p -> CompletableFuture.supplyAsync(() -> p.getKey() + ":" + p.getValue(id),CustomThreadPool.INSTANCE))
.collect(toList());
result = futureList.stream().map(p->getVal(p,"")).collect(joining(","));
endTime = System.currentTimeMillis();
System.out.println(String.format("CompletableFuture的自定义线程池消耗时间:%d,返回结果:%s", (endTime - startTime), result));
} private static <T>T getVal(Future<T> future,T defaultV){
try {
return future.get(2,TimeUnit.SECONDS);
}catch (Exception ex){
return defaultV;
}
}
} interface UserFeatureable {
String getKey(); String getValue(int id);
} class GetCareerUserFeature implements UserFeatureable { @Override
public String getKey() {
return "career";
} @Override
public String getValue(int id) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { }
return "10";
}
} class GetTradeUserFeature implements UserFeatureable { @Override
public String getKey() {
return "trade";
} @Override
public String getValue(int id) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { }
return "5";
}
} class GetVipLevelUserFeature implements UserFeatureable { @Override
public String getKey() {
return "vip";
} @Override
public String getValue(int id) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { }
return "v1";
}
}

2.自定义线程池配置

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class CustomThreadPool {
/**
* 默认核心线程池大小
*/
private static final int DEFAULT_CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors(); /**
* 最大线程池大小
* 最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目
* 最佳线程数目 = (1s/0.1s + 1) * CPU数目
*/
private static final int DEFAULT_MAXIMUM_POOL_SIZE = 11 * DEFAULT_CORE_POOL_SIZE; /**
* 超过核心线程后,空闲线程等待时间
*/
private static final long DEFAULT_KEEP_ALIVE_SECONDS = 10; /**
* 等待执行的线程队列
*/
private static BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingDeque(DEFAULT_MAXIMUM_POOL_SIZE * 2); public static ThreadPoolExecutor INSTANCE = new ThreadPoolExecutor(
DEFAULT_CORE_POOL_SIZE,
DEFAULT_MAXIMUM_POOL_SIZE,
DEFAULT_KEEP_ALIVE_SECONDS,
TimeUnit.SECONDS,
WORK_QUEUE,
new ThreadFactoryBuilder().setNameFormat("task-pool-thread-%d").build()); }

3.结果

parallelStream消耗时间:2889,返回结果:career:10,trade:5,vip:v1
CompletableFuture的ForkJoin线程池消耗时间:1010,返回结果:career:10,trade:5,vip:v1
CompletableFuture的自定义线程池消耗时间:1011,返回结果:career:10,trade:5,vip:v1

java并行之parallelStream与CompletableFuture比较的更多相关文章

  1. Java 并行与并发

    Java 并行与并发 注意两个词:并行(Concurrent) 并发(Parallel) 并行:是逻辑上同时发生,指在某一个时间内同时运行多个程序 并发:是物理上同时发生,指在某一个时间点同时运行多个 ...

  2. Java并发程序设计(二)Java并行程序基础

    Java并行程序基础 一.线程的生命周期 其中blocked和waiting的区别: 作者:赵老师链接:https://www.zhihu.com/question/27654579/answer/1 ...

  3. JAVA并行程序基础

    JAVA并行程序基础 一.有关线程你必须知道的事 进程与线程 在等待面向线程设计的计算机结构中,进程是线程的容器.我们都知道,程序是对于指令.数据及其组织形式的描述,而进程是程序的实体. 线程是轻量级 ...

  4. 避坑 | Java8使用并行流(ParallelStream)注意事项

    示例分析 /** * 避坑 | Java8使用并行流(ParallelStream)注意事项 * * @author WH.L * @date 2020/12/26 17:14 */ public c ...

  5. JAVA并行程序基础二

    JAVA并行程序基础二 线程组 当一个系统中,如果线程较多并且功能分配比较明确,可以将相同功能的线程放入同一个线程组里. activeCount()可获得活动线程的总数,由于线程是动态的只能获取一个估 ...

  6. JAVA并行程序基础一

    JAVA并行程序基础一 线程的状态 初始线程:线程的基本操作 1. 新建线程 新建线程只需要使用new关键字创建一个线程对象,并且用start() ,线程start()之后会执行run()方法 不要直 ...

  7. Java8使用并行流(ParallelStream)注意事项

    Java8并行流ParallelStream和Stream的区别就是支持并行执行,提高程序运行效率.但是如果使用不当可能会发生线程安全的问题.Demo如下: public static void co ...

  8. JAVA使用并行流(ParallelStream)时要注意的一些问题

    https://blog.csdn.net/xuxiaoyinliu/article/details/73040808

  9. Java:并行编程及同步使用方法

    知道java可以使用java.util.concurrent包下的 CountDownLatch ExecutorService Future Callable 实现并行编程,并在并行线程同步时,用起 ...

随机推荐

  1. Python打开文件open()的注意事项

    刚刚用open(fileName)来打开txt格式的文件,总是出现错误,总是找不到文件读取的内容,后来才发现是open()在使用过程中自动关闭了.这里介绍另种方法解决这个问题. 第一种方法. with ...

  2. 如何把App放在服务器上供用户下载

    如何把App放在服务器上供用户下载 有时候做了个简单的App想把App给朋友帮忙测试一下,却发现上传到各种平台很麻烦,肿么办?难道一个个拷贝,那也太low啦,不是咱程序员该干的事儿,好的话不多说,开搞 ...

  3. 【转载】Reactor模式,或者叫反应器模式

    Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤,或 ...

  4. 从《数据挖掘概念与技术》到《Web数据挖掘》

    从<数据挖掘概念与技术>到<Web数据挖掘> 认真读过<数据挖掘概念与技术>的第一章后,对数据挖掘有了更加深刻的了解.数据挖掘是知识发展过程的一个步骤.知识发展的过 ...

  5. jmeditor与CKEditor4x整合的BUG

    整合页面的代码:   显示效果如下: 一直查不出来什么问题.根据网友的建议作了下面的修改.仍然不能正常显示公式: 不过上面网友的代码第2行有问题,没写完整.不知道替换成什么样的代码. 修改代码如下: ...

  6. hdu 4281 Judges' response(多旅行商&DP)

    Judges' response Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. (译)C#参数传递

    前言 菜鸟去重复之Sql的问题还没有得到满意的答案.如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了. 接触C#一年了,感觉很多东西还是很模糊,像C#中的委托和事件 有些东西看多了不用也还是不 ...

  8. mdadm 软RAID

    mdadm是linux下用于创建和管理软件RAID的命令,是一个模式化命令.但由于现在服务器一般都带有RAID阵列卡,并且RAID阵列卡也很廉价,且由于软件RAID的自身缺陷(不能用作启动分区.使用C ...

  9. Linux Socket - UDP链接包

    LINUX UDP SOCKET 01 UDP号绑定会报错吗? 会的,提示Address is using,本地的没有区别 UDP不需要发起链接,不知道是不是连接成功 client的IP地址和端口号不 ...

  10. [react002] component基本用法

    1 什么是component 设计接口的时候,把通用的设计元素(按钮,表单框,布局组件等)拆成接口良好定义的可复用的组件. 这样,下次开发相同界面程序时就可以写更少的代码,也意义着更高的开发效率,更少 ...