使用线程池测试cpu的并发计算能力
接到一个需求是测试一下cpu并发计算能力,针对int和float求和单位时间能执行几次的问题。可能是服务器选型用到的参数。
开始使用的是fork-join,但是发现fork-join每次得到的结果值波动很明显不稳定(可能和fork-join的实现有关系,抽空研究一下),所以用了线程池的思路来实现
ps:
当然你可以把这篇文章作为线程池和Callable结合并发计算的一个demo来看
代码如下:
package com.company; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; /**
* @author nf
* 多线程累加求和
*
*/
public class CpuTestByThreadPool{
private ThreadPoolExecutor pool = null;
public void init(int poolCount) {
pool = new ThreadPoolExecutor(
poolCount,
poolCount*2,
30,
TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(10));
}
public void destory() {
if(pool != null) {
pool.shutdownNow();
}
}
private class Sum implements Callable<Integer>{
private int subMin;
private int subMax;
private int[] arr;
public Sum(int subMin,int subMax,int[] arr){
this.subMin = subMin;
this.subMax = subMax;
this.arr = arr;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i = subMin;i <= subMax;i++){
sum += arr[i];
}
return sum;
}
} /**
* 求和范围是 min ~ max
* @param min
* @param max
* @param threadNum
* @return
*/
public Integer getSum(int min, int max,int[] arr, int threadNum){
int subMin;
int subMax;
List<FutureTask<Integer>> taskList = new ArrayList<>();
int sumCounts = max - min;
int subCounts = sumCounts/threadNum;
int remainder = sumCounts%threadNum;
int mark = min;
for(int i = 0;i<threadNum;i++){
subMin = mark;
if(remainder!=0&&remainder>i){
subMax = subMin + subCounts;
}else{
subMax = mark + subCounts - 1;
}
mark = subMax + 1;
FutureTask<Integer> task = new FutureTask<Integer>(new Sum(subMin,subMax,arr));
taskList.add(task);
pool.execute(new Thread(task));
}
int sum = taskListSum(taskList);
return sum;
} private Integer taskListSum(List<FutureTask<Integer>> taskList){
int sum = 0;
for(FutureTask<Integer> task : taskList){
try {
sum += task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return sum;
} private class SumFloat implements Callable<Float>{
private int subMin;
private int subMax;
private Float[] arr;
public SumFloat(int subMin,int subMax,Float[] arr){
this.subMin = subMin;
this.subMax = subMax;
this.arr = arr;
}
@Override
public Float call() throws Exception {
Float sum = 0f;
for(int i = subMin;i <= subMax;i++){
sum += arr[i];
}
return sum;
}
} /**
* 求和范围是 min ~ max
* @param min
* @param max
* @param threadNum
* @return
*/
public Float getSumFloat(int min, int max,Float[] arr, int threadNum){
int subMin;
int subMax;
List<FutureTask<Float>> taskList = new ArrayList<>();
int sumCounts = max - min;
int subCounts = sumCounts/threadNum;
int remainder = sumCounts%threadNum;
int mark = min;
for(int i = 0;i<threadNum;i++){
subMin = mark;
if(remainder!=0&&remainder>i){
subMax = subMin + subCounts;
}else{
subMax = mark + subCounts - 1;
}
mark = subMax + 1;
FutureTask<Float> task = new FutureTask<Float>(new SumFloat(subMin,subMax,arr));
taskList.add(task);
pool.execute(new Thread(task));
}
Float sum = taskListSumFloat(taskList);
return sum;
} private Float taskListSumFloat(List<FutureTask<Float>> taskList){
Float sum = 0f;
for(FutureTask<Float> task : taskList){
try {
sum += task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return sum;
} /**
* @param args
* 测试
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException{
//修改这三个参数
final int arrSize = 2800000,sleeptime=10000;
final int poolCount = 10;
int[] arr = new int[arrSize];
for (int i = 0; i < arrSize; i++) {
arr[i] = i + 1;
} Float[] arrFloat = new Float[arrSize];
for (int i = 0; i < arrSize; i++) {
arrFloat[i] = i + (((float)i) / 3f);
}
CpuTestByThreadPool sumCalculator = new CpuTestByThreadPool(); sumCalculator.init(poolCount);
long startTime = 0L;
long endTime = 0L;
long countL=0L,countF=0L;
startTime = System.nanoTime();
while ((endTime-startTime)<10000000000L) {//10秒
sumCalculator.getSum(0, arrSize,arr, poolCount);
endTime = System.nanoTime();
countL++;
}
System.out.println(countL);
Thread.sleep(sleeptime);
endTime = 0L;
startTime = System.nanoTime();
while ((endTime-startTime)<10000000000L) {
sumCalculator.getSumFloat(0, arrSize, arrFloat, poolCount);
endTime = System.nanoTime();
countF++;
}
System.out.println(countF);
sumCalculator.destory(); System.out.println("TPCC= " + (countL+countF)/2 + "tpmC");
} }
可以通过修改arrSize = 2800000;poolCount = 10;这两个参数匹配自己的机器(让运行时cpu内核占满就行了)
使用线程池测试cpu的并发计算能力的更多相关文章
- [原创] JAVA 递归线程池测试 ExecutorService / ForkJoinPool
测试工具使用递归的方式获取子进程的Msg消息,目前有2种常用的ExecutorService / ForkJoinPool 为了测试哪种效果较好,我们来写个测试Demo,循环5555555次+1(加锁 ...
- JAVA 递归线程池测试 ExecutorService / ForkJoinPool
测试工具使用递归的方式获取子进程的Msg消息,目前有2种常用的ExecutorService / ForkJoinPool 为了测试哪种效果较好,我们来写个测试Demo,循环5555555次+1(加锁 ...
- 【重学Java】多线程进阶(线程池、原子性、并发工具类)
线程池 线程状态介绍 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态.线程对象在不同的时期有不同的状态.那么Java中的线程存在哪几种状态呢?Java中的线程 状态被定 ...
- javaWeb 使用线程池+队列解决"订单并发"问题
解决方式:使用线程池+队列 项目基于Spring,如果不用spring需要自己把 ThreadPoolManager.java 改成单例模式 1.写一个Controller(Spring mvc) / ...
- 线程池大小 & cpu core
http://stackoverflow.com/questions/14556037/number-of-processor-core-vs-the-size-of-a-thread-pool ht ...
- Java并发(二十一):线程池实现原理
一.总览 线程池类ThreadPoolExecutor的相关类需要先了解: (图片来自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8% ...
- python 之 线程池实现并发
使用线程池实现高IO并发 模块:ThreadPoolExecutor, as_completed 测试代码如下: #!/opt/python3/bin/python3 from concurrent. ...
- 并发编程(六)--进程/线程池、协程、gevent第三方库
一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上百个或上千个,手动创建就较为繁琐,这时就可 ...
- 并发编程(六)——进程/线程池、协程、gevent第三方库
进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...
随机推荐
- PAT T1022 Werewolf
暴力搜索加剪枝~ #include<bits/stdc++.h> using namespace std; ; int a[maxn]; bool visit[maxn]; vector& ...
- GitHub 网站汉化
居然是一个中文Github网站!该不会是个假的吧? 2018-09-03 17:30 前几天分享了一篇文章——3个搜索技巧!在 GitHub上快速找到实用资源!眼尖心细的读者发现了文中的Github网 ...
- Java基础 -4.4
For循环 for循环也是一种常规的使用结构 public static void main(String[] args) { for(定义循环的初始值;循环判断;修改循环条件) { 循环语句的执行; ...
- 整理了一下NLP中文数据集
个人理解: 句子相似性判断.情感分析.实体识别.智能问答,本质基本上都是分类任务. 阅读理解(抽取式.回答式.完形填空)是逐个候选项的分类问题处理. 参考 https://github.com/chi ...
- RGB 和 YUV 的转换公式
- intelliJ IDEA 全屏键盘手
从MyEclipse到IntelliJ IDEA --让你脱键盘,全键盘操作 从MyEclipse转战到IntelliJ IDEA的经历 我一个朋友写了一篇"从Eclipse到Android ...
- Java 在Excel单元格中应用一种/多种字体样式
在Excel表格中,设置单元格字体样式时,可以对单元格内的所有字符应用同一样式,即获取指定单元,应用样式即可:另外也可以对单元格内的不同字符内容应用不同字体样式,即获取单元格中的字符位置,应用样式:本 ...
- PE之RVA转FOA
目录 公式 实验-对齐大小一样 获取ImageBase 计算RVA 获取内存对齐和文件对齐 判断在哪一个节 计算偏移 获取节表的PointerToRawData 计算FOA 验证 实验-对齐大小不一样 ...
- change事件和input事件的区别
input事件: input事件在输入框输入的时候回实时响应并触发 change事件: change事件在input失去焦点才会考虑触发,它的缺点是无法实时响应.与blur事件有着相似的功能,但与bl ...
- HashMap ( Java 8)
HashTable是早起java提供的基于hash表的实现,不允许存放null键和值,是同步的,影响开销,不太被推荐. HashMap行为上和HashTable差不多,不是同步的,允许键和值为null ...