java线程池的参数设置

java线程池的参数设置

在说如何对线程池优化之前重复一下线程的7大参数

  • corePoolSize: 核心线程数,也是线程池中常驻的线程数,线程池初始化时默认是没有线程的,当任务来临时才开始创建线程去执行任务

  • maximumPoolSize: 最大线程数,在核心线程数的基础上可能会额外增加一些非核心线程,需要注意的是只有当workQueue队列填满时才会创建多于corePoolSize的线程(线程池总线程数不超过maxPoolSize)

  • keepAliveTime: 非核心线程的空闲时间超过keepAliveTime就会被自动终止回收掉,注意当corePoolSize=maxPoolSize时,keepAliveTime参数也就不起作用了(因为不存在非核心线程);

  • unit: keepAliveTime的时间单位

  • workQueue: 用于保存任务的队列,可以为无界、有界、同步移交三种队列类型之一,当池子里的工作线程数大于corePoolSize时,这时新进来的任务会被放到队列中

  • threadFactory: 创建线程的工厂类,默认使用Executors.defaultThreadFactory(),也可以使用guava库的ThreadFactoryBuilder来创建

  • handler: 线程池无法继续接收任务(队列已满且线程数达到maximunPoolSize)时的饱和策略,取值有AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy、DiscardPolicy

核心线程设置

计算密集型

当线程执行的是计算密集型的任务,那么要尽量防止线程的上下文切换,所以要设置的线程数要较少一点,一般设置为 线程数 = CPU核数+1,也可以设置成CPU核数*2

I/0密集型

在 WEB 应用中 涉及到大量的 i/o传输 , 一旦发生IO,线程就会处于等待状态,当IO结束,数据准备好后,线程才会继续执行。我们可以多设置一些线程池中线程的数量,这样就能让在等待IO的这段时间内,其他线程可以去做其它事,提高并发处理效率。对于IO密集型应用:
线程数 = CPU核心数/(1-阻塞系数) 这个阻塞系数一般为0.8~0.9之间,也可以取0.8或者0.9

其他参数设置

  1. 根据不同的场景选择不同适合的拒绝策略 , 也可以实现RejectedExecutionHandler接口自定义拒绝策略
  2. 使用线程工厂创建线程时正确的对线程命名,便于排查问题
  3. 我们也可以调用shutdown来手动终止线程池。如果我们忘记调用shutdown,为了让线程资源被释放,我们还可以使用keepAliveTime 和 allowCoreThreadTimeOut来达到目的
  4. ThreadPoolExecutor提供了protected类型可以被覆盖的钩子方法,我们可以使用beforeExecute和afterExecute来记录线程之前前和后的一些运行情况

你可能感兴趣的:(java,并发编程,java)