使用Executors工具类创建的三种线程池,不推荐这么创建线程池,在阿里巴巴开发手册中提出,使用工具类创建的线程池因为最大线程数默认Integer.MAX_VALUE
约为21亿,会造成OOM。
三大方法
Executors.newSingleThreadExecutor();//创建只有一个线程的线程池
Executors.newCachedThreadPool();//创建一个最大线程数为Integer.MAX_VALUE的线程池
Executors.newFixedThreadPool(5);//创建一个核心线程数和最大线程数为传入参数的线程池
七大参数
corePoolSize
:核心线程数,线程池初始创建的线程数
maximumPoolSize
:最大线程数量。任务数量超过核心线程数,就会将任务放到队列中,队列满了,就会启动非核心线程执行任务,线程数超过这个限制就会走拒绝策略。
keepAliveTime
:等待超时时间,空闲线程等待的时间
unit
:等待时间单位
workQueue
:阻塞队列,当线程池中的任务超过当前最大核心线程数,会将后来的任务放到此队列,当队列满,会开启新的线程执行队列中的第一个任务。
threadFactory
:线程工厂,用来创建线程的
handler
:拒绝策略,当任务数已达到最大线程数,并且阻塞队列已满时执行的拒绝策略
四种拒绝策略
AbortPolicy
:如果阻塞队列满,则不再处理新的任务,并且抛出异常
CallerRunsPolicy
:如果阻塞队列满,则将这个任务返回给创建这个任务的线程去处理,不抛出异常
DiscardOldestPolicy
:如果阻塞队列满了,则丢弃阻塞队列里面的任务,添加新的任务,不抛出异常
DiscardPolicy
:如果阻塞队列满了,则丢掉任务,不抛出异常
手动创建线程池
//创建一个核心线程数为2,最大线程数为5,超时等待3S,阻塞队列大小为3,使用默认线程工厂(线程工厂一般不用修改,使用默认即可),AbortPolicy策略的线程池。
new ThreadPoolExecutor(2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
上述线程池的运行规则为:初始创建2个线程,当任务超过2,则会创建新的线程,当任务数大于最大线程数+阻塞队列之和既大于8时会执行拒绝策略,除核心线程以外的线程会在空闲3S后被回收。
最大线程数如何定义最好?
1.CPU密集型:CPU核心是多少就将最大线程数定义为多少
Runtime.getRuntime().availableProcessors()//获取CPU核心数
2.IO密集型:设置大于你的程序中十分耗IO资源的线程数的值,一般为2倍