根据IBM提供的设置建议
The optimum size of a thread pool depends on the number of processors available and the nature of the tasks on the work queue. On an N-processor system for a work queue that will hold entirely compute-bound tasks, you will generally achieve maximum CPU utilization with a thread pool of N or N+1 threads.
For tasks that may wait for I/O to complete – for example, a task that reads an HTTP request from a socket – you will want to increase the pool size beyond the number of available processors, because not all threads will be working at all times. Using profiling, you can estimate the ratio of waiting time (WT) to service time (ST) for a typical request. If we call this ratio WT/ST, for an N-processor system, you’ll want to have approximately N(1+WT/ST)* threads to keep the processors fully utilized.
可以得出:
对于CPU密集型任务,设置大小为:
线程数 = CPU核数+1
对于IO密集型任务,设置大小为:
线程数 = (1+线程等待时间/线程CPU时间 )* CPU占有率 * CPU核心数 (0 < CPU占有率 <=1)
当然,这并不绝对。例如很多文章中表示JDK1.8做了并行计算优化,对于CPU密集型任务最大值为:
线程数 = CPU内核线程数*2
测试机核心数:2
JDK版本:1.8
下面我将定义一个Size为4的线程池,使用这个线程池执行20个线程。输出线程执行耗时,线程等待耗时,线程总耗时。
得出结果后再把刚刚结果输入控制台,计算各项综合及其平均值。
public class Snippet {
private static final int POOL_SIZE = 4;
private static final int Thread_SIZE = 20;
private static final int AWAIT_TIME = 10;
private static List SERVICE_TIMES = new ArrayList<>();
private static List WAITING_TIMES = new ArrayList<>();
private static List TOTAL_TIMES = new ArrayList<>();
public static void main(String[] args) throws Exception {
testThreadTime();
calcTime();
}
public static void calcTime() throws IOException {
System.out.println("Thread "+SERVICE_TIMES.size());
System.out.println(SERVICE_TIMES);
System.out.println(sum(SERVICE_TIMES));
System.out.println(average(SERVICE_TIMES));
System.out.println();
System.out.println("Waiting "+WAITING_TIMES.size());
System.out.println(WAITING_TIMES);
System.out.println(sum(WAITING_TIMES));
System.out.println(average(WAITING_TIMES));
System.out.println();
System.out.println("Total "+TOTAL_TIMES.size());
System.out.println(TOTAL_TIMES);
System.out.println(sum(TOTAL_TIMES));
System.out.println(average(TOTAL_TIMES));
}
public static int sum(List list) {
int sum = 0;
for(int tmp : list){
sum += tmp;
}
return sum;
}
public static int average(List list) {
int sum = 0;
for(int tmp : list){
sum += tmp;
}
return sum/list.size();
}
public static void testThreadTime() throws InterruptedException {
Snippet tmp = new Snippet();
char name = 'a';
ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE);
for(int i=0;i
得出结果:
Thread 20
[4752, 4752, 4752, 4752, 31, 31, 87, 31, 84, 100, 32, 37, 37, 38, 32, 23, 16, 16, 15, 15]
19633.0
981.65
Waiting 20
[0, 0, 0, 0, 4752, 4783, 4752, 4814, 4767, 4752, 4840, 4845, 4852, 4851, 4873, 4882, 4889, 4889, 4905, 4905]
77351.0
3867.55
Total 20
[4752, 4752, 4752, 4752, 4783, 4814, 4839, 4845, 4851, 4852, 4872, 4882, 4889, 4889, 4905, 4905, 4905, 4905, 4920, 4920]
96984.0
4849.2
而从结果可以得出:
线程执行时间分布:前四个耗时4700+,其他的耗时<100
线程等待时间分布:前四个耗时0,其他的4700-4905
线程等待时间分布:总体都在4800±100 ,幅度不大。
于是我们可以推断:
----未完待持续…