java池化技术

**写在前面**

    在Java应用开发中经常会用到连接池、线程池等池化技术。池化(pool)技术的本质是通过复用对象、连接等资源,减少创建对象/连接,降低垃圾回收(GC)的开销,适当使用池化相关技术能够显著提高系统效率,优化性能。

**线程池**

- Java ThreadPoolExecutor

线程池通过减少频繁创建和销毁线程来降低系统性能损耗。每一个线程会对应一个线程栈(Thread Stack),用于存储局部变量与操作信息,可通过JVM参数中 -Xss 来调整线程栈大小,同时通过线程池来控制可创建线程的数量。线程池一般和队列(work queue)配合工作,通过线程池限制处理并发任务的数量;然后使用队列做为缓冲,通过设置队列的深度,当任务数量超过队列深度时,采用相应的拒绝策略处理,保证系统的可用性。

```java

ThreadPoolExecutor构造方法

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue,

                          RejectedExecutionHandler handler) {

    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

        Executors.defaultThreadFactory(), handler);

```

**参数解析**

corePoolSize:核心线程数量,是线程池维护的线程最小数量。它会一直存活,即使没有任务,线程池也会维护线程的最少数量。

maximumPoolSize:线程池维护线程的最大数量。

keepAliveTime: 线程池维护线程所允许的空闲时间,当线程空闲时间达到keepAliveTime,该线程会退出,直到线程数量等于corePoolSize。如果allowCoreThreadTimeout设置为true,则所有线程均会退出直到线程数量为0。

unit:线程池维护线程所允许的空闲时间的单位、可选参数值为:TimeUnit中的几个静态属性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。

workQueue:线程池所使用的缓冲队列,包括有界堵塞队列ArrayBlockingQueue、链表阻塞队列LinkedBlockingQueue、无缓冲阻塞队列SynchronousQueue。

handler:线程池中的数量大于maximumPoolSize,对拒绝任务的处理策略,包括Abort(直接抛出RejectExecutionException),Discard(按照LIFO丢弃)、DiscardOldest(按照LRU丢弃)、CallsRun(主线程执行),默认值ThreadPoolExecutor.AbortPolicy()。

策略说明

当一个任务通过execute(Runnable)方法欲添加到线程池时:

如果当前线程池中的数量小于corePoolSize,并线程池处于Running状态,创建并添加的任务。

如果当前线程池中的数量等于corePoolSize,并线程池处于Running状态,缓冲队列 workQueue未满,那么任务被放入缓冲队列、等待任务调度执行。

如果当前线程池中的数量大于corePoolSize,缓冲队列workQueue已满,并且线程池中的数量小于maximumPoolSize,新提交任务会创建新线程执行任务。

如果当前线程池中的数量大于corePoolSize,缓冲队列workQueue已满,并且线程池中的数量等于maximumPoolSize,新提交任务由Handler处理。

当线程池中的线程大于corePoolSize时,多余线程空闲时间超过keepAliveTime时,会关闭这部分线程。

![](https://img-blog.csdnimg.cn/20200701101904917.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg0NTExNg==,size_16,color_FFFFFF,t_70)

**建议显式设置队列深度**

使用Executor.newFixedThreadPool时,没有显式设置work queue队列大小(默认为Integer.MAX_VALUE),队列深度过大导致瞬间线程数量巨大;

如果大量任务被缓存到LinkedBlockingQueue中等待线程执行,会导致垃圾回收(GC)消耗大,系统响应慢以及内存溢出(OOM);

## Tomcat ThreadPool(base on tomcat 8.5)

tomcat的线程池相关配置支持Http Connector与Executor两种,下面分别说明。

**Http Connector**

*参考:http://tomcat.apache.org/tomcat-8.5-doc/config/http.html*

```java

Tomcat-Http-Connector

<Connector port="8080" acceptCount="100" maxConnections="200" minSpareThreads="10" maxThreads="200" />

```

**主要参数解析**

acceptCount:请求等待队列大小。当Tomcat没有空闲线程处理连接请求时,新请求将被放入等待队列;当队列深度超过acceptCount后,新请求直接被拒绝,默认值为100。

maxConnections:能够处理的最大并发连接数。当超过后会将新的连接放入等待队列,连接会等待并不会被处理。默认值根据Connector的类型会有区别,BIO为200,NIO、NIO2为10000,APR为8192。

minSpareThreads:线程池最小连接数,即可维护的最小连接数,默认值为10。

maxThreads:线程池最大连接数,当线程空闲一段时间后会释放,直到minSparethreads数量,默认值为200。

**配置建议**

Tomcat最大并发线程数石油maxConnections与maxThreads中较小的值决定。

例如:

并发请求200个,accessCount=100,maxConnections=50,maxThreads=100;

则说明有50个线程处理50个并发连接,100个线程进入等待队列,其余50个请求被拒绝。

Executor(org.apache.catalina.Executor)方式配置

*参考:http://tomcat.apache.org/tomcat-8.5-doc/config/executor.html*

```java

Tomcat-Executor

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" daemon="true" minSpareThreads="25" maxThreads="200" maxIdleTime="60000" maxQueueSize="Integer.MAX_VALUE" prestartminSpareThreads="false" />

<Connector port="8080" executor="tomcatThreadPool" executorTerminationTimeoutMills="5000"/>

```

**主要参数解析**

namePrefix:线程池创建的线程名称前缀。

daemon:是否以守护进程方式运行,默认为true。

minSpareThreads:线程池最小线程数,默认值为25。

maxThreads:线程池最大连接数,默认值为200。

maxIdleTime:空闲线程的存活时间,超过此时间线程将会被回收,默认值为60秒。

maxQueueSize:任务队列深度,默认为Integer.MAX_VALUE。

prestartminSpareThreads:是否在Tomcat启动时就在线程池中创建minSpareThreads个线程,默认值为false。

executorTerminationTimeoutMills:在停止Executor时,等待请求处理线程终止的超时时间,默认值为5000毫秒(5秒)。

配置建议

maxQueueSize默认值为Integer.MAX_VALUE,在常规场景过大,建议通过压测合理调整此值;

关注公众号一起探讨技术:***码农翻身之道***

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容