前言
Java中创建线程的多种方式:1.继承Thread类 2.实现Runnable接口
而线程池主要是Java封装了一个能够自动控制线程并发数量的类,在阿里巴巴规范上说,创建线程池时自己手动创建效果最佳.也就是通过: ThreadPoolExecutor es = new ThreadPoolExecutor(...)的方式创建线程池.而线程池中有一个入参是ThreadFactory,也就是线程工厂,可以自己手动创建,也可以通过 Executors的默认线程工厂.
创建一个简单的线程工厂:
//请求队列,当线程池中的线程数量达到
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
//线程池中核心线程数的最大值(不是操作系统的最大值)
int corePoolSize = 10;
//最大队列空间
int maximumPoolSize = 50;
//表示空闲线程的存活时间
long keepAliveTime = 100L;
//keepAliveTime的单位
TimeUnit unit = TimeUnit.SECONDS;
//线程池的拒绝策略
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
//创建一个新的线程池
ThreadPoolExecutor es = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
Executors.defaultThreadFactory(),
handler);
创建线程池时的各个参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {...}
这个是最完成的构造方法,方法入参有7个,而且除了三个基本类型其他都是很怪异的参数.
除基本类型以外的类型参数,具体选择哪些可以戳这个链接:https://blog.csdn.net/jubaoquan/article/details/79198780
线程池参数的具体作用
线程池可以理解为蓄水槽,当没有水也就是没有请求的时候,没有线程存活在线程池中时,没有线程在进行排水工作.当请求出现时,一个线程处理一个请求,而当一个线程处理完请求后,它会继续存活一定的时间,避免当下一个线程出现时还有申请新的线程空间造成时间上的浪费,而线程存活的时间,也就是空闲线程的存活时间为keepAliveTime,这个时间的单位是TimeUnit.
而当线程池中的数量达到最大线程池数量,也就是maximumPoolSize时,新来的请求就要放入队列里等待.队列就是BlockingQueue<Runnable> workQueue.
当队列中等待的线程数塞满时,再来新的请求,线程池就会增大自己的线程,使其超过maximumPoolSize的值.就这样一直重复,直到线程数到达系统支持的最大值.此时如果在队列已满的情况下,又收到了新的请求,就会根据handler,也就是根据拒绝策略做出相应的处理,拒绝或者别的策略.
ThreadFoctory可以自己去定义一个实现了ThreadFactory接口的线程工厂,也可以直接用Executors.defaultThreadFactory(),即默认的线程工厂.