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采用了异步.事件 ...
随机推荐
- vim的语法高亮及配置文件说明
本文主要针对那些刚刚入门的菜鸟,老手请自动忽略,谢谢. 一.安装vim: sudo pacman -S vim 随后根据提示输入超级用户密码即可完成安装 二.配置自己的语法高亮文件,主要是修改-/.v ...
- Android下设置CPU核心数和频率
现在的Android手机双核.四核变得非常普遍,同时CPU频率经常轻松上2G,功耗肯定会显著增加.而大多数的ARM架构的CPU采用的是对称多处理(SMP)的方式处理多CPU.这就意味着每个CPU核心是 ...
- Syslog协议日志格式翻译
通用日志格式规范(参考 RFC5424 Syslog协议) 下面是RFC5424 Syslog协议关于信息格式的定义. Syslog信息的格式定义 # 一条信息的构成 SYSLOG-MSG = HEA ...
- 无法启动Visual Studio的localhost web服务器,端口"xxxx"已被使用
解决方法:项目属性-Web里面有web服务器端口的设置,换个端口即可.项目属性->web->服务器,不要选择“自动分配端口”,选择“使用指定端口”,后面输入一个端口号
- Linux centos 时间不同步 date 和 hwclock 时间不一致
Linux centos 时间不同步 date 和 hwclock 网站有两台服务器,date 查看差3分钟 在应用 APP倒计时 与 直播,时时性较强的功能应用中 请求服务器后返回的服务器时间与数据 ...
- 洛谷——P1227 [JSOI2008]完美的对称
P1227 [JSOI2008]完美的对称 题目描述 在峰会期间,必须使用许多保镖保卫参加会议的各国代表.代表们除了由他自己的随身保镖保护外,组委会还指派了一些其他的特工和阻击手保护他们.为了使他们的 ...
- GCJ——Crazy Rows (2009 Round 2 A)
题意: 给定一个N*N的矩阵,由0,1组成,只允许交换相邻的两行,把矩阵转化为下三角矩阵(对角线上方全是0),最少需要多少次交换?(保证可以转化为下三角矩阵) Large: N<=40 解析: ...
- CTAS都能带走源表的哪些属性
CREATE TABLE ... AS SELECT statement(CTAS):用CTAS语句可以根据一个存在的表创建一个新的表,而且能够根据对应的过滤条件将源表部分或者全部数据插入到新表当中. ...
- 【lombok】lombok---帮你简化生成必要但臃肿的java代码工具 【映射注解和lombok注解同时使用 以及 映射注解放在属性和get方法上的区别】
官方地址:https://projectlombok.org/ GitHub:https://github.com/rzwitserloot/lombok 指导说明文档:http://jnb.ociw ...
- 配置和使用服务器Tomcat连接池
1.配置Tomcat6.0根目录\conf\context.xml <?xml version='1.0' encoding='utf-8'?> <!-- Licensed to t ...