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采用了异步.事件 ...
随机推荐
- python3列表推导式和生成器。
1.把一个字符串变成 Unicode 码位的列表 >>> symbols = '$¢£¥€¤' >>> codes = [] >>> for sy ...
- 初学Docker容器网络不得不看的学习笔记
一.关于Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后 ...
- vue.js移动端app实战2
貌似有部分人要求写的更详细,这里多写一点vuel-cli基础的配置 什么是vue-cli? 官方的解释是:A simple CLI for scaffolding Vue.js projects,简单 ...
- luogu P3147 [USACO16OPEN]262144
题目描述 Bessie likes downloading games to play on her cell phone, even though she doesfind the small to ...
- jzyzoj 栈——P1148:括号匹配加强版
括号匹配加强版 描述 Description 对于一个由(,),[,]括号组成的字符串,求出其中最长的括号匹配字串. 具体来说,满足如下条件的字符串成为括号匹配的字符串: (1) (),[] 是括号匹 ...
- Css 基础学习
css 基本选择器 css基本选择器有三种方法 第一种: class选择器 .c1{ color: red;} <div class='c1'>hello world</div> ...
- require_once(): Failed opening required '/var/www/config/config.php' (include_path='.:') in /var/www/vendor/forkiss/pharest/src/Pharest/Register/Register.php on line 10
环境 docker环境 错误 [Tue Jun 18 18:43:26 2019] 127.0.0.1:53980 [500]: /index.php - require_once(): Failed ...
- 【Salvation】——怪物角色动画&主角碰撞死亡动画
写在前面:这个动画功能同样也是使用JavaScript编写脚本,在Unity3D游戏引擎的环境中实现,在怪物的角色动画中,很多与人物相同,这里不再重复. 一.设计敌人 拖一个精英sprite到层次面板 ...
- VIM正则表达式查找替换
0. 一些需要注意的不同 VIM中的正则表达式和其他的有点不一样 (1) 有些符号要用\转义,比如\+表示重复一次或以上,其他的还有一些,:h pattern查看(2) 非贪婪匹配用\{-}, 如 ...
- HDU 3466 01背包变形
给出物品数量N和总钱数M 对于N个物品.每一个物品有其花费p[i], 特殊值q[i],价值v[i] q[i] 表示当手中剩余的钱数大于q[i]时,才干够买这个物品 首先对N个物品进行 q-p的排序,表 ...