线程池的概念
线程池是一种多线程使用模式,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。不同的线程池启动线程和停止线程的模式不一样,整体而言线程池会提供空闲线程执行任务。
线程池的工作机制
- 线程池模式下,接受任务的主体是线程池,线程池将任务分配给线程。
- 线程池负责线程的启动,停止,状态监管,任务分配。
线程池的优势
线程池提供线程的创建,启动,执行,停止,并发等管理功能,使用线程池可以避免系统线程管理的开销和风险。降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行;
Java线程池详解
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
corePoolSize(线程池基本大小):在任务队列未满之前,线程池维护的线程数量。创建方式可以是按需创建,也可以是初始化创建。按需创建,当有新任务提交给线程池时,如果线程数小于corePoolSize,线程池会创建新的线程来提供服务。
maximumPoolSize(线程池最大大小):在任务队列满后,线程池无空闲线程提供服务,此时会创建新的线程来提供服务,线程最大数不能超过maximumPoolSize。
keepAliveTime(线程存活保持时间):maximumPoolSize-corePoolSize数量线程的存活时间,当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。
workQueue(任务队列):用于传输和保存等待执行任务的阻塞队列。
handler(线程饱和策略):当线程池和队列都满了,再加入任务会执行此策略。
线程池为什么要使用阻塞队列而不使用非阻塞队列
首先不阻塞队列是个什么情况这个我没想象出来,这个就像我们去快餐店吃饭,客人不多的时候,营业员可以直接为我们服务(无阻塞队列),人多的时候,要排队然后依次为我们服务。如果人再多那就添加店员为我们服务,一切都是顺理成章。对于线程池来说。阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源。
线程池配置技巧
这个跟线程池的任务类型有关,线程池任务类型从宏观上说可以分为CPU密集型和IO密集型两种。CPU密集型任务,一般为CPU核心数+1。IO密集型任务可以使用稍大的线程池,一般为2*CPU核心数。
java中提供的线程池
Executors类提供了4种不同的线程池:CachedThreadPool, FixedThreadPool, ScheduledThreadPool, SingleThreadExecutor
- CachedThreadPool:适用于负载较轻,执行短期异步任务的场景。
- FixedThreadPool:适用于负载较重的场景,避免线程切换,创建带来的性能消耗。
- ScheduledThreadPool:适用于执行延时或者周期性任务。
- SingleThreadExecutor:适用于顺序执行的场景。