计算线程池设置工具

//////////////////////////////////////////////////////////////////////////////////////////////////

package com.zyxy.admin.config;

import java.math.BigDecimal;

import java.math.RoundingMode;

import java.util.Timer;

import java.util.TimerTask;

import java.util.concurrent.BlockingQueue;

/**

* A class that calculates the optimal thread pool boundaries. It takes the desired target utilization and the desired

* work queue memory consumption as input and retuns thread count and work queue capacity.

*

* @author Niklas Schlimm

*

*/

public abstract class PoolSizeCalculator {

/**

    * The sample queue size to calculate the size of a single {@link Runnable} element.

*/

    private final int SAMPLE_QUEUE_SIZE =1000;

/**

* Accuracy of test run. It must finish within 20ms of the testTime otherwise we retry the test. This could be

* configurable.

*/

    private final int EPSYLON =20;

/**

* Control variable for the CPU time investigation.

*/

    private volatile boolean expired;

/**

* Time (millis) of the test run in the CPU time calculation.

*/

    private final long testtime =3000;

/**

    * Calculates the boundaries of a thread pool for a given {@link Runnable}.

*

    * @param targetUtilization

    *            the desired utilization of the CPUs (0 <= targetUtilization <= 1)

    * @param targetQueueSizeBytes

    *            the desired maximum work queue size of the thread pool (bytes)

*/

    protected void calculateBoundaries(BigDecimal targetUtilization, BigDecimal targetQueueSizeBytes) {

calculateOptimalCapacity(targetQueueSizeBytes);

Runnable task = creatTask();

start(task);

start(task);// warm up phase

        long cputime = getCurrentThreadCPUTime();

start(task);// test intervall

        cputime = getCurrentThreadCPUTime() - cputime;

long waittime = (testtime *1000000) - cputime;

calculateOptimalThreadCount(cputime, waittime, targetUtilization);

}

private void calculateOptimalCapacity(BigDecimal targetQueueSizeBytes) {

long mem = calculateMemoryUsage();

BigDecimal queueCapacity = targetQueueSizeBytes.divide(new BigDecimal(mem), RoundingMode.HALF_UP);

System.out.println("Target queue memory usage (bytes): " + targetQueueSizeBytes);

System.out.println("createTask() produced " + creatTask().getClass().getName() +" which took " + mem

+" bytes in a queue");

System.out.println("Formula: " + targetQueueSizeBytes +" / " + mem);

System.out.println("* Recommended queue capacity (bytes): " + queueCapacity);

}

/**

* Brian Goetz' optimal thread count formula, see 'Java Concurrency in Practice' (chapter 8.2)

*

    * @param cpu

    *            cpu time consumed by considered task

    * @param wait

    *            wait time of considered task

    * @param targetUtilization

    *            target utilization of the system

*/

    private void calculateOptimalThreadCount(long cpu,long wait, BigDecimal targetUtilization) {

BigDecimal waitTime =new BigDecimal(wait);

BigDecimal computeTime =new BigDecimal(cpu);

BigDecimal numberOfCPU =new BigDecimal(Runtime.getRuntime().availableProcessors());

BigDecimal optimalthreadcount = numberOfCPU.multiply(targetUtilization).multiply(

new BigDecimal(1).add(waitTime.divide(computeTime, RoundingMode.HALF_UP)));

System.out.println("Number of CPU: " + numberOfCPU);

System.out.println("Target utilization: " + targetUtilization);// 目标利用率

        System.out.println("Elapsed time (nanos): " + (testtime *1000000));// 运行时间

        System.out.println("Compute time (nanos): " + cpu);// 计算时间

        System.out.println("Wait time (nanos): " + wait);// 等待时间

        System.out.println("Formula: " + numberOfCPU +" * " + targetUtilization +" * (1 + " + waitTime +" / "

                + computeTime +")");// 计算公式

        System.out.println("* Optimal thread count: " + optimalthreadcount);// 最佳线程数

    }

/**

    * Runs the {@link Runnable} over a period defined in {@link #testtime}. Based on Heinz Kabbutz' ideas

* (http://www.javaspecialists.eu/archive/Issue124.html).

*

    * @param task

    *            the runnable under investigation

*/

    public void start(Runnable task) {

long start =0;

int runs =0;

do {

if (++runs >5) {

throw new IllegalStateException("Test not accurate");

}

expired =false;

start = System.currentTimeMillis();

Timer timer =new Timer();

timer.schedule(new TimerTask() {

public void run() {

expired =true;

}

},testtime);

while (!expired) {

task.run();

}

start = System.currentTimeMillis() - start;

timer.cancel();

}while (Math.abs(start -testtime) >EPSYLON);

collectGarbage(3);

}

private void collectGarbage(int times) {

for (int i =0; i < times; i++) {

System.gc();

try {

Thread.sleep(10);

}catch (InterruptedException e) {

Thread.currentThread().interrupt();

break;

}

}

}

/**

* Calculates the memory usage of a single element in a work queue. Based on Heinz Kabbutz' ideas

* (http://www.javaspecialists.eu/archive/Issue029.html).

*

    * @return memory usage of a single {@link Runnable} element in the thread pools work queue

*/

    public long calculateMemoryUsage() {

BlockingQueue queue = createWorkQueue();

for (int i =0; i

queue.add(creatTask());

}

long mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

long mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

queue =null;

collectGarbage(15);

mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

queue = createWorkQueue();

for (int i =0; i

queue.add(creatTask());

}

collectGarbage(15);

mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

return (mem1 - mem0) /SAMPLE_QUEUE_SIZE;

}

/**

* Create your runnable task here.

*

    * @return an instance of your runnable task under investigation

*/

    protected abstract Runnable creatTask();

/**

* Return an instance of the queue used in the thread pool.

*

    * @return queue instance

*/

    protected abstract BlockingQueue createWorkQueue();

/**

* Calculate current cpu time. Various frameworks may be used here, depending on the operating system in use. (e.g.

* http://www.hyperic.com/products/sigar). The more accurate the CPU time measurement, the more accurate the results

* for thread count boundaries.

*

    * @return current cpu time of current thread

*/

    protected abstract long getCurrentThreadCPUTime();

}

//////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////

package com.zyxy.admin.config;

import java.lang.management.ManagementFactory;

import java.math.BigDecimal;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

public class MyPoolSizeCalculatorextends PoolSizeCalculator{

public static void main(String[] args)throws InterruptedException,

InstantiationException,

IllegalAccessException,

ClassNotFoundException {

MyPoolSizeCalculator calculator =new MyPoolSizeCalculator();

calculator.calculateBoundaries(new BigDecimal(1.0),

new BigDecimal(100000));

ThreadPoolExecutor pool =

new ThreadPoolExecutor(6,6,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue(2500));

}

protected long getCurrentThreadCPUTime() {

return ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();

}

protected Runnable creatTask() {

//        return new AsynchronousTask(0, "IO", 1000000);

        return null;

}

protected BlockingQueue createWorkQueue() {

return new LinkedBlockingQueue<>();

}

}

//////////////////////////////////////////////////////////////////////////////////////////////////


http://www.itkeyword.com/doc/695091929758357438/java-thread

你可能感兴趣的:(计算线程池设置工具)