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采用了异步.事件 ...
随机推荐
- 刷leetcode是什么样的体验?【转】
转自:https://www.zhihu.com/question/32322023 刷leetcode是什么样的体验? https://leetcode.com/ 1 条评论 默认排序 按时间排 ...
- python 复习-2
把一个数字的list从小到大排序,然后写入文件,然后从文件中读取出来文件件内容,然后反序,再追加到文件的下一行中 """把一个数字的list从小到大排序,然后写入文件,然 ...
- TeamViewer下载地址
http://www.teamviewer.com/zhCN/download/linux.aspx Ubuntu配置远程访问的xrdp协议和teamviewer软件 先启用远程设置:System-& ...
- [转]谈谈Java中的语法糖
*该博客转自 http://blog.csdn.net/danchu/article/details/54986442 语法糖(Syntactic Sugar),也称糖衣语法,指在计算机语言中添加的某 ...
- luogu P1314 聪明的质监员
题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...
- [JLOI2015]有意义的字符串
4002: [JLOI2015]有意义的字符串 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1000 Solved: 436[Submit][St ...
- Using Find_Alert and Show_Alert in Oracle Forms
Show_alert is used to display model window messages in Oracle Forms and Find_alert searches the list ...
- VS2010中 报错:error C2146、error C4430 原因一:缺少CvvImage类
今天用vs2010打开vs2008的一个工程,报了好多错: 1>e:\visual studio 2010\projects\imageprojects\morphology\morpholog ...
- 【Todo】Python中文及Java中文问题及解决方法总结 & 及各种字符编码问题跟踪贴
Python中文编码问题看这里吧:http://www.cnblogs.com/charlesblc/p/6159109.html Mysql中文编码问题可以看这篇:http://www.cnblog ...
- 【GLSL教程】(九)其他说明 【转】
http://blog.csdn.net/racehorse/article/details/6664775 法线矩阵 在很多顶点shader中都用到了gl_NormalMatrix.这里将介绍这个矩 ...