Java 线程池的探讨

221 阅读3分钟

连接池相关配置是工作中必定用到的,也是面试中常被问到的问题。

一、数据库连接池和线程池的区别

数据库连接池:

1,连接池是面对数据库连接的。

2,连接池是为了优化数据库连接资源的。

3,连接池有点类似在客户端做优化。

线程池:

1,线程池是面对后台程序的。

2,线程池是为了提高内存和CPU效率

3,线程池有点类似在服务端做优化。

但总而言之,两者区别不大,都是利用池化技术来提高性能和效率,核心配置都差不多。

二、线程池核心配置参数

corePoolSize:线程池的核心线程数

maximunmPoolSize:线程池的最大线程数

keepAliveTime:超过核心线程数时闲置的线程的存活时间

workQueue:任务执行前保存任务的队列,保存由execute方法提交的Runnable任务

RejectedExecutionHandler handler:拒绝策略, 当提交过多的任务时而不能及时处理,可以用拒绝策略来处理

一个执行过程如下图,图来自网络。

三、Java默认实现好的线程池有哪些

1,SingleThreadExecutor线程池

这个线程池只有一个核心线程在工作,相当于是单线程串行执行任务。

corePoolSize:1

maximunmPoolSize:1

keepAliveTime:0L

workQueue:new LinkedBlockingQueue()

2,FixedThreadPool 线程池

FixedThreadPool 是固定大小的线程池,只有核心线程。每次提交一个任务会创建一个线程,直到达到核心线程数大小,就不会再增加线程了。

FixedThreadPool对数针对一些很稳定很固定的正规并发线程,多用于服务器。

corePoolSize:nThreads

maximunmPoolSize:corePoolSize:nThreads

keepAliveTime:0L

workQueue:new LinkedBlockingQueue()

3,CachedTheadPool 线程池

CachedTheadPool是无界线程池,当有任务来且没有空闲线程时,就会新增线程来处理,当由空闲线程空闲了60秒,则会回收这些线程。线程池的大小完全依赖于操作系统能够创建的最大线程大小。

缓存型池子通常用于执行一些生存期很短的异步型任务。因此在一些面向连接的deamon型的SERVER中用的不多。但对于生存期短的异步任务,它是首选。

corePoolSize:0

maximunmPoolSize:Integer.MAX_VALUE

keepAliveTime:60L

workQueue:new SynchronousQueue(),一个是缓冲区为1的阻塞队列

4,ScheduledThreadPool 线程池

ScheduledThreadPool :核心线程池固定,大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。如果闲置,非核心线程会在DEFAULT_KEEPALIVE_MILLIS时间回收。

corePoolSize:corePoolSize

maximunmPoolSize:Integer.MAX_VALUE

keepAliveTime:DEFAULT_KEEPALIVE_MILLIS

workQueue:new DelayedWorkQueue(),一个是缓冲区为1的阻塞队列

四、四种线程池拒绝策略

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务

ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

线程池的默认拒绝策略为AbortPolicy,即丢弃任务并抛出RejectedExecutionException异常。

选择哪一种拒绝策略,一定要根据业务需求来,每一种策略都有利有弊。

五、关于核心线程数大小的问题

1,corePoolSize核心线程数

Runtime.getRuntime().availableProcessors():获取cpu核心数。但此方法在部分的电脑上不够准确,尽量避免使用此方法。

corePoolSize数不是越大越好,最优的是解决CPU核心数量即可。

CPU密集计算:N+1

IO类型的:2N

扩展:参考这篇文章,了解线程数多反而影响性能。blog.csdn.net/zzzgd_666/a…