线程池的大小有时候会让人难以决定,所以通常会将线程池的大小设置成CPU的倍数,那问题就来了,一般线程池大小一般该设计成cpu的多少倍呢?下面一起来了解一下吧。
例:
package com.lc.concurrent; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class MyThreadPoolExecutor { //最大可用的CPU核数 public static final int PROCESSORS = Runtime.getRuntime() .availableProcessors(); //线程最大的空闲存活时间,单位为秒 public static final int KEEPALIVETIME = 60; //任务缓存队列长度 public static final int BLOCKINGQUEUE_LENGTH = 500; public ThreadPoolExecutor createThreadPool() { return new ThreadPoolExecutor(PROCESSORS * 2, PROCESSORS * 4, KEEPALIVETIME, TimeUnit.SECONDS , new ArrayBlockingQueue < Runnable > (BLOCKINGQUEUE_LENGTH)); } }
以上面例子来说,池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可。
我们关心的主要是核心池线程的数量该如何设置。线程中的任务最终是要交给CPU的线程去处理的,而CPU可同时处理线程数量大部分是CPU核数的两倍,在运行环境中CPU的核数我们可以通过Runtime.getRuntime().availableProcessors()
方法获取。理论上来说核心池线程数量应该是为Runtime.getRuntime().availableProcessors()*2,现在我们就来测试一下结果吧。
例:
package com.lc.concurrent; import java.util.Arrays; import java.util.Random; import java.util.concurrent.ThreadPoolExecutor; public class CreateThreads { public synchronized static void main(String[] args) { System.out.println(MyThreadPoolExecutor.PROCESSORS); new CreateThreads() .test(); } public synchronized void test() { ThreadPoolExecutor threadPoolExecutor = new MyThreadPoolExecutor() .createThreadPool(); for (int i = 0; i <= 100; i++) { MyTask myTask = new MyTask(i); threadPoolExecutor.execute(myTask); } threadPoolExecutor.shutdown(); } } class MyTask implements Runnable { private int i; public MyTask(int i) { this.i = i; } @Override public void run() { System.out.println("任务" + i + "开始执行" + System.currentTimeMillis()); for (int i = 0; i < 32766; i++) { Random random = new Random(); int randNum = random.nextInt(); int[] a = { 1 , 2 , 3 , 4 , 5 , 6 , 9 , 18 , 290 , 238 , 991 , 100 , 19 , 1932 , randNum }; Arrays.sort(a); Arrays.hashCode(a); Arrays.stream(a); } System.out.println("任务" + i + "结束执行" + System.currentTimeMillis()); } }
我的电脑CPU核数为4,可以同时处理8线程,测试结果如下:
核心池线程数量 执行耗时( 毫秒, 多次测试结果以 / 间隔)
核心池线程数量 执行耗时( 毫秒, 多次测试结果以 / 间隔) 4 474 / 479 / 471 8 430 / 436 / 421 12 432 / 425 / 438 16 437 / 431 / 449 20 471 / 481 / 469
我们看到,当线程数量小于CPU核数两倍时速度会明显下降,超过两倍后速度会相差不多,当核心池数量过多时,速度又会显著下降。
由此我们得出,核心池线程数量大小应在CPU核数两倍以上且不过多,这样是比较合适的。
以上就是本篇文章的所有内容了,线程池一直是java中的重要功能,想要了解更多线程池相关java常见问答知识,就请持续关注奇Q工具网吧。
推荐阅读: