Executors几种常用的线程池性能比较
java编程中,经常会利用Executors的newXXXThreadsPool生成各种线程池,今天写了一小段代码,简单测试了下三种常用的线程池:

import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; /**
* 测试类(因为要用到forkjoin框架,所以得继承自RecursiveXXX)
*/
public class MathTest extends RecursiveAction { private List<Integer> target; private static AtomicInteger count = new AtomicInteger(0); public MathTest(List<Integer> list) {
this.target = list;
} public double process(Integer d) {
//模拟处理数据耗时200ms
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println("thread:" + Thread.currentThread().getId() + "-" + Thread.currentThread().getName() + ", d: " + d);
return d;
} @Override
protected void compute() {
if (target.size() <= 2) {
for (Integer d : target) {
process(d);
count.incrementAndGet();
}
return;
}
int mid = target.size() / 2;
MathTest t1 = new MathTest(target.subList(0, mid));
MathTest t2 = new MathTest(target.subList(mid, target.size()));
t1.fork();
t2.fork();
} public static void main(String[] args) {
int num = 100;
int threadCount = 4;
List<Integer> target = new ArrayList<>(num);
for (int i = 0; i < num; i++) {
target.add(i);
} MathTest test = new MathTest(target); //原始方法,单线程跑
long start = System.currentTimeMillis();
for (int i = 0; i < target.size(); i++) {
test.process(target.get(i));
}
long end = System.currentTimeMillis();
System.out.println("原始方法耗时:" + (end - start) + "\n"); //固定线程池
final ThreadFactory fixedFactory = new ThreadFactoryBuilder().setNameFormat("fixed-%d").build();
ExecutorService service = Executors.newFixedThreadPool(threadCount, fixedFactory); count.set(0);
start = System.currentTimeMillis();
for (Integer d : target) {
service.submit(() -> {
test.process(d);
count.incrementAndGet();
});
}
while (true) {
if (count.get() >= target.size()) {
end = System.currentTimeMillis();
System.out.println("fixedThreadPool耗时:" + (end - start) + "\n");
break;
}
} //cached线程池
final ThreadFactory cachedFactory = new ThreadFactoryBuilder().setNameFormat("cached-%d").build();
service = Executors.newCachedThreadPool(cachedFactory);
count.set(0);
start = System.currentTimeMillis();
for (Integer d : target) {
service.submit(() -> {
test.process(d);
count.incrementAndGet();
});
}
while (true) {
if (count.get() >= target.size()) {
end = System.currentTimeMillis();
System.out.println("cachedThreadPool耗时:" + (end - start) + "\n");
break;
}
} //newWorkStealing线程池
service = Executors.newWorkStealingPool(threadCount);
count.set(0);
start = System.currentTimeMillis();
for (Integer d : target) {
service.submit(() -> {
test.process(d);
count.incrementAndGet();
});
}
while (true) {
if (count.get() >= target.size()) {
end = System.currentTimeMillis();
System.out.println("workStealingPool耗时:" + (end - start) + "\n");
break;
}
} //forkJoinPool
ForkJoinPool forkJoinPool = new ForkJoinPool(threadCount);
count.set(0);
start = System.currentTimeMillis();
forkJoinPool.submit(test);
while (true) {
if (count.get() >= target.size()) {
end = System.currentTimeMillis();
System.out.println("forkJoinPool耗时:" + (end - start) + "\n");
break;
}
} }
}
代码很简单,就是给一个List,然后对里面的每个元素做处理(process方法),用三种线程池分别跑了一下,最后看耗时,输出如下:
原始方法耗时:20156 fixedThreadPool耗时:5145 cachedThreadPool耗时:228 workStealingPool耗时:5047 forkJoinPool耗时:5042
环境:mac + intel i5(虚拟4核)。 workStealingPool内部其实就是ForkJoin框架,所以二者在耗时上基本一样,符合预期;如果业务的处理时间较短,从测试结果来看,cachedThreadPool最快。
Executors几种常用的线程池性能比较的更多相关文章
- Android 四种常见的线程池
引入线程池的好处 1)提升性能.创建和消耗对象费时费CPU资源 2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多. 我们来看一下线程池的简单的构造 public ThreadPoolExec ...
- Executors相关的类(线程池)
一.概述 Java是天生就支持并发的语言,支持并发意味着多线程,线程的频繁创建在高并发及大数据量是非常消耗资源的,因为java提供了线程池.在jdk1.5以前的版本中,线程池的使用是及其简陋的,但是在 ...
- java开发中几种常见的线程池
线程池 java.util.concurrent:Class Executors 常用线程池 几种常用的的生成线程池的方法: newCachedThreadPool newFixedThreadPoo ...
- 【java】之常用四大线程池用法以及ThreadPoolExecutor详解
为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率2.线程并发数量过多,抢占系统资源从而导致阻塞3.对线程进行一些简单的管理 在Java中,线程池 ...
- Java常用四大线程池用法以及ThreadPoolExecutor详解
为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率 2.线程并发数量过多,抢占系统资源从而导致阻塞 3.对线程进行一些简单的管理 在Java中,线 ...
- Java 四种内置线程池
引言 我们之前使用线程的时候都是使用 new Thread 来进行线程的创建,但是这样会有一些问题 每次 new Thread 新建对象性能差 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可 ...
- NGINX引入线程池 性能提升9倍
1. 引言 正如我们所知,NGINX采用了异步.事件驱动的方法来处理连接.这种处理方式无需(像使用传统架构的服务器一样)为每个请求创建额外的专用进程或者线程,而是在一个工作进程中处理多个连接和请求.为 ...
- Java常用的线程池
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...
- Nginx 学习笔记(六)引入线程池 性能提升9倍
原文地址:https://www.cnblogs.com/shitoufengkuang/p/4910333.html 一.前言 1.Nignx版本:1.7.11 以上 2.NGINX采用了异步.事件 ...
随机推荐
- uva 1149:Bin Packing(贪心)
题意:给定N物品的重量,背包容量M,一个背包最多放两个东西.问至少多少个背包. 思路:贪心,最大的和最小的放.如果这样都不行,那最大的一定孤独终生.否则,相伴而行. 代码: #include < ...
- Hbuilder 快捷键
最近在学习javaweb 在学前端的时候用到了一款国产编辑器 很棒 Hbuilder 快捷键 Ctrl + d 删除整行内容 Ctrl + Shift +R ...
- json.net(Json.NET - Newtonsoft)利用动态类解析json字符串
将对象转换为字符串很简单,唯一要注意的点就是为了避免循环要在需要的字段上添加jsonignore属性.可以参照这篇博文:http://www.mamicode.com/info-detail-1456 ...
- 牛客网 Wannafly挑战赛8 A.小Y和小B睡觉觉
写了一会不想写了... A-小Y和小B睡觉觉 链接:https://www.nowcoder.com/acm/contest/57/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制: ...
- Codeforces Gym 101471D Money for Nothing(2017 ACM-ICPC World Finals D题,决策单调性)
题目链接 2017 ACM-ICPC World Finals Problem D (这题细节真的很多) 把所有的(pi,di)按横坐标升序排序. 对于某个点,若存在一个点在他左下角,那么这个点就是 ...
- POJ 2486 Apple Tree [树状DP]
题目:一棵树,每个结点上都有一些苹果,且相邻两个结点间的距离为1.一个人从根节点(编号为1)开始走,一共可以走k步,问最多可以吃多少苹果. 思路:这里给出数组的定义: dp[0][x][j] 为从结点 ...
- NOI模拟题4 Problem A: 生成树(mst)
Solution 我们考虑答案的表达式: \[ ans = \sqrt{\frac{\sum_{i = 1}^{n - 1} (w_i - \overline{w})^2}{n - 1}} \] 其中 ...
- Windows 10系统出现:“出现系统还原使用的卷影复制服务无法运行...”的问题解决
在服务中是:Volume Shadow Copy和Microsoft Software Shadow Copy Provider这两项.把它开启.
- visual studio 2010 调试
非startup project网站 通过attach to process 添加进程w3wp可以实现断点调试 若有多个,可以在iis中添加应用程序池,然后在网站的高级设置里设置应用程序池里,选择对 ...
- 每天学一点Python(2)
9月16日(python扩展的安装和使用) 接着上一篇继续.按照之前计划,先分析导出的数据,再做进一步统计. 导出的数据是html类型的,想到的处理方法有: 1.直接readlines然后一行一行找我 ...