• 使用线程池测试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内核占满就行了)

  • 相关阅读:
    沮丧
    实例讲解《Microsoft AJAX Library》(1):DomElement类
    linux0.12系统调用
    关于中断
    dd写img
    linux系统中堆栈的使用方法
    浅析程序的装载
    SourceInsight3.5序列号
    区分进程的逻辑地址空间中段和cpu分段机制中段的概念
    32位计算机的4G可寻址空间
  • 原文地址:https://www.cnblogs.com/nfsnyy/p/10334943.html
Copyright © 2020-2023  润新知