一、线程池
线程池是一种基于池化思想的多线程处理形式,它通过预先创建一定数量的线程来处理任务队列中的任务。线程池的主要优势在于:
池化思想:是一种通过创建和管理可重复使用的对象池来提高性能和资源利用率的编程思想。它的核心概念是在需要时从池中获取对象,而不是每次都创建新的对象,使用完毕后将对象返回到池中,以供其他代码复用。
好处:
1.减少创建和销毁线程的开销
2.有效控制运行的线程数
3.提供更好的管理机制
二、线程池的创建
2.1线程池的核心参数
corePoolSize
:核心线程数,线程池的基本大小,即在没有新任务提交时,线程池中保持的最小线程数。
maximumPoolSize
:最大线程数,线程池允许的最大线程数。
keepAliveTime
:空闲线程存活时间,空闲线程等待新任务的最长时间,超过这个时间后线程会被终止(如果当前线程数大于corePoolSize
)。
workQueue
:是一个阻塞队列,用于存储提交给线程池但尚未开始执行的任务,通常可以选择ArrayBlockingQueue(基于数组的,
适用于任务数量有限且需要防止资源耗尽的场景)
, LinkedBlockingQueue(基于链表的,
适用于任务数量不确定且希望有较大缓冲能力的场景)
等阻塞队列。
2.2创建线程池
可以通过Executors工具类进行快速创建线程池(不推荐):
1.newFixedThreadPool ——固定线程数
2.newSingleThreadExecutor——单一线程池
3.newCachedThreadPool——具有缓存功能
4.newScheduledThreadPool——周期性线程池
面试题:为什么不推荐使用Executors工具类快速创建线程池?
这些方法在某些情况下可能会导致资源耗尽或性能问题
-
FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE(最大21亿左右,如果打满了会相当占用内存),可能会堆积大量的请求,从而导致 OOM。
-
CachedThreadPool和newScheduledThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。
2.3自定义线程池
void test1() {
ExecutorService executor = new ThreadPoolExecutor(3, // corePoolSize
5, // maximumPoolSize
100L, // keepAliveTime
TimeUnit.SECONDS,//时间单位为秒
new ArrayBlockingQueue<>(3)// workQueue
);
for (int i = 1; i <=8; i++){
executor.execute(()->{
System.out.println(Thread.currentThread().getName() + "执行任务");
//循环8次并打印当前线程
try {
Thread.sleep(500);//线程休眠500毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
try {
Thread.currentThread().sleep(1000);//主线程休眠1000毫秒保证所有线程都有机会执行
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
executor.shutdown();//关闭线程池
}
三、线程池生命周期
1.RUNNING:线程池创建后的初始状态,可以提交新任务,可以处理工作队列中的任务。
2.SHUTDOWN:线程池关闭状态,不再接受新的任务,但是仍然可以处理工作队列中的任务。
3.STOP:不接受新任务,不处理排队任务,中断进行中的任务。
4.TIDYING:所有任务都已终止,workerCount 为零,TIDYING是过渡状态将运行 terminated() 方法。
5.TERMINATED:terminated() 方法已经执行完毕,线程池已关闭。
四、拒绝策略
.AbortPolicy:抛出RejectedExecutionException异常,拒绝提交任务,是线程池默认拒绝策略。
2.CallerRunsPolicy:当线程池无法处理新任务时(即线程池中的线程数已经达到最大值,且工作队列已满),该策略会将任务交由调用execute方法的线程来执行。这种策略既不会抛弃任务,也不会抛出异常,而是将任务回推到调用者。
3.DiscardOldestPolicy:丢弃队列中等待时间最长的任务(即最旧的任务),然后尝试将新任务添加到队列中。
4.DiscardPolicy:啥都不做,丢弃任务。