接到一个需求是测试一下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的并发计算能力的更多相关文章

  1. [原创] JAVA 递归线程池测试 ExecutorService / ForkJoinPool

    测试工具使用递归的方式获取子进程的Msg消息,目前有2种常用的ExecutorService / ForkJoinPool 为了测试哪种效果较好,我们来写个测试Demo,循环5555555次+1(加锁 ...

  2. JAVA 递归线程池测试 ExecutorService / ForkJoinPool

    测试工具使用递归的方式获取子进程的Msg消息,目前有2种常用的ExecutorService / ForkJoinPool 为了测试哪种效果较好,我们来写个测试Demo,循环5555555次+1(加锁 ...

  3. 【重学Java】多线程进阶(线程池、原子性、并发工具类)

    线程池 线程状态介绍 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态.线程对象在不同的时期有不同的状态.那么Java中的线程存在哪几种状态呢?Java中的线程 状态被定 ...

  4. javaWeb 使用线程池+队列解决"订单并发"问题

    解决方式:使用线程池+队列 项目基于Spring,如果不用spring需要自己把 ThreadPoolManager.java 改成单例模式 1.写一个Controller(Spring mvc) / ...

  5. 线程池大小 & cpu core

    http://stackoverflow.com/questions/14556037/number-of-processor-core-vs-the-size-of-a-thread-pool ht ...

  6. Java并发(二十一):线程池实现原理

    一.总览 线程池类ThreadPoolExecutor的相关类需要先了解: (图片来自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8% ...

  7. python 之 线程池实现并发

    使用线程池实现高IO并发 模块:ThreadPoolExecutor, as_completed 测试代码如下: #!/opt/python3/bin/python3 from concurrent. ...

  8. 并发编程(六)--进程/线程池、协程、gevent第三方库

    一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上百个或上千个,手动创建就较为繁琐,这时就可 ...

  9. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

随机推荐

  1. 泛型和Object的区别?

    泛型声明 public <T> T doSomeThing(T t){ return t; } Object声明 public Object doSomeThing(Object obj) ...

  2. ElementUI el-message 提示信息的用法

    引入message Element 注册了一个$message方法用于调用,Message 可以接收一个字符串或一个 VNode 作为参数,它会被显示为正文内容. Element 为 Vue.prot ...

  3. 第九届蓝桥杯B组决赛 调手表(完全背包)

    问题描述 M78 星云的一个小时有 n 分钟. 大家都知道,手表只有一个按钮可以把当前的数加一.在调分钟的时候,如果当前显示的数是 0 ,那么按一下按钮就会变成 1,再按一次变成 2 .如果当前的数是 ...

  4. selenium webdriver 相关网站

    ITeye:http://shijincheng0223.iteye.com/blog/1481446 http://ztreeapi.iteye.com/blog/1750554 http://sm ...

  5. XPath简介

    参考视频:   https://www.bilibili.com/video/av49809274/?p=22 一,什么是XPATH? xpath(xml path language)是一门在xml和 ...

  6. 01初步启动Hadoop服务

    1.rz命令将hadoop压缩包上传至Linux服务器中 2.tar -zxvf hadoop-2.7.7.tar.gz(解压即可用) 3.将解压出来的hadoop移到想要放的位置 mv hadoop ...

  7. Android开发:界面设计之六大layouts介绍

    1.帧布局 FrameLayout: FrameLayout是最简单的布局对象.在它里面的的所有显示对象都将固定在屏幕的左上角,不能指定位置,后一个会直接覆盖在前一个之上显示 因为上面的一段话这个是在 ...

  8. H5不支持的标签

    <acronym> 定义首字母缩写. <applet>  定义applet <basefont> 定义文档中所有文本的默认颜色.大小和字体.请用CSS代替  < ...

  9. RHEL6配置CentOS yum源

    RHEL6配置CentOS yum源

  10. 访问docker desktop创建的Hyper-v虚拟机DockerDesktopVM

    平常我们部署kubernetes ,一般都是先安装个linux操作系统,不管是centos或者ubuntu或者其他,都是我们手工操作的.安装好的这个操作系统都开启了SSH,能够远程登录访问. 但是do ...