java_线程池7大参数_底层运行原理
int corePoolSize:线程池中常驻的核心线程数;
int maximumPoolSize:线程池中能够容纳同时执行的最大线程数,此值必须大于等于1;
long keepAliveTime:多余的空闲线程的存活时间,当前线程池数量超过corePoolSize的时候,
当空闲时间达到keepAliveTime值时,多余空闲线程会被销毁,直到只剩下corePoolSize个线程为止;
TimeUnit unit:keepAliveTime的单位;
BlockingQueue<Runnable> workQueue:任务队列(阻塞队列),被提交但尚未被执行的任务处处于阻塞队列中;
ThreadFactory threadFactory:表示生产线程池中工作线程的线程工厂,用于创建线程,一般用默认的即可;
RejectedExecutionHandler handler:拒绝策略,当队列满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize);
RejectedExecutionHandler handler:四种拒绝策略:
AbortPolicy(默认):直接抛出RejectedExecutionException阻止系统正常运行;
CallerRunsPolicy:“调用者模式”,一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某个任务回退到调用者,从而降低新任务的流量;
DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务;
DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案;
注意:
再生产环境下,三种常见创建线程池的方法都不会去使用,通常是自定义创建一个线程池;
ExecutorService threadPool = new ThreadPoolExecutor( 2,//当前线程池常驻线程数 5,//当前线程池最大线程数 1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位 new LinkedBlockingDeque<>(3),//阻塞队列,长度为3 Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的 new ThreadPoolExecutor.AbortPolicy());//拒绝策略,AbortPolicy()默认的
示例代码如下:
import java.util.concurrent.*; //线程池 public class MyThreadPoolDemo { public static void main(String[] args) { ExecutorService threadPool = new ThreadPoolExecutor( 2,//当前线程池常驻线程数 5,//当前线程池最大线程数 1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位 new LinkedBlockingDeque<>(3),//阻塞队列,长度为3 Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的 new ThreadPoolExecutor.AbortPolicy());//拒绝策略,AbortPolicy()默认的 try { //模拟10个用户办理业务 for (int i = 1; i <= 10; i++) { threadPool.execute(() ->{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); //TimeUnit.SECONDS.sleep(1);//每一秒钟只有一个人来办理业务 } }catch (Exception e){ e.printStackTrace(); }finally { threadPool.shutdown(); } } }
更改线程池如下:
ExecutorService threadPool = new ThreadPoolExecutor( 2,//当前线程池常驻线程数 5,//当前线程池最大线程数 1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位 new LinkedBlockingDeque<>(3),//阻塞队列,长度为3 Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的 new ThreadPoolExecutor.CallerRunsPolicy());//拒绝策略,AbortPolicy()默认的
更改线程池如下:
ExecutorService threadPool = new ThreadPoolExecutor( 2,//当前线程池常驻线程数 5,//当前线程池最大线程数 1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位 new LinkedBlockingDeque<>(3),//阻塞队列,长度为3 Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的 new ThreadPoolExecutor.DiscardOldestPolicy());//拒绝策略,AbortPolicy()默认的
更改线程池如下:
ExecutorService threadPool = new ThreadPoolExecutor( 2,//当前线程池常驻线程数 5,//当前线程池最大线程数 1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位 new LinkedBlockingDeque<>(3),//阻塞队列,长度为3 Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的 new ThreadPoolExecutor.DiscardPolicy());//拒绝策略,AbortPolicy()默认的
线程池中最大线程数应该如何配置:
CPU密集型(需要大量的运算)
IO密集型:
第一种情况:
第二种情况: