接到一个需求是测试一下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. 01初步启动Hadoop服务

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

  2. Python学习笔记004

    变量 变量的命名规则1. 要具有描述性2. 变量名只能_,数字,字母组成,不可以是空格或特殊字符(#?<.,¥$*!~)3. 不能以中文为变量名4. 不能以数字开头,下划线或者小写字母开头,驼峰 ...

  3. centso7设置防火墙

    CentOS 7默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防火墙 1 2 3 systemctl stop firewalld.service #停止f ...

  4. Jlink不报错的方法

    https://blog.csdn.net/yekui6254/article/details/85272767 方法:安装最新的jlink驱动,按下面网址下载 OllyDBG软件,根据上面说的方法修 ...

  5. Android。WebView加载UR请求使用Cookie储存User_Id记录用户是否登陆过

    1.WebView初始化的时候用倒如下代码: if (Build.VERSION.SDK_INT >= 21) { CookieManager.getInstance().setAcceptTh ...

  6. docker的私有化仓库harbor搭建

    目前比较流行的docker私有化仓库是harbor,harbor是一个github开源的项目,直接在github上搜索即可,下载地址:https://github.com/goharbor/harbo ...

  7. linux 基本命令学习总结

    1. linux的目录结构  (linux核心:一切皆文件) 目录结构解释 (主要的有 /etc  /home  /mnt  /opt  /usr   /tmp) 相对路径和绝对路径的区别 绝对路径  ...

  8. DRF项目之序列化器和视图重写方法的区别

    我们,都知道,DRF框架是一款高度封装的框架. 我们可以通过重写一些方法来实现自定义的功能. 今天,就来说说在视图中重写和序列化器中重写方法的区别. 在视图中重写方法: 接收请求,处理数据(业务逻辑) ...

  9. yii 框架 – 安全站点和非安全站点的 URL 管理

    在本文中我将描述怎么管理安全站点和非安全站点的 URL 管理. 安全站点的内容使用httpsSSL (安全套接字层) 协议发送,而非安全站点使用http协议.为了描述简单,我们称前者https内容/页 ...

  10. Spring之IOC、AOP和事务

    IOC 什么是IOC?如果你回答:Spring是个IOC容器,实现原理是反射,没了.这样证明你没有真正理解IOC. IOC的意思是控制反转,还有个外号叫依赖注入(DI).为什么起这么晦涩难懂的名字呢? ...