优化策略:采用线程池
- 核心思想:通过复用已有的线程来处理新的客户端连接请求,避免频繁创建和销毁线程带来的开销,从而有效控制线程数量,防止线程资源耗尽。
- 代码实现:
- 创建线程池:在Java中,可以使用
ThreadPoolExecutor
类来创建线程池。以下是一个简单示例:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Server {
// 定义线程池参数
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 10;
private static final long KEEP_ALIVE_TIME = 10L;
private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
private static final BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<>(100);
// 创建线程池
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE_TIME,
TIME_UNIT,
WORK_QUEUE);
public static void main(String[] args) {
// 模拟客户端连接请求
for (int i = 0; i < 20; i++) {
final int clientNumber = i;
executor.submit(() -> {
System.out.println("处理客户端连接 " + clientNumber + " ,线程名称:" + Thread.currentThread().getName());
// 模拟业务处理
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池
executor.shutdown();
}
}
- 线程池参数设置及原因:
CORE_POOL_SIZE
(核心线程数):设置为5,这表示线程池在正常情况下会保持5个线程处于活动状态,即使这些线程暂时没有任务。这个值的设置要根据项目预计的常规负载来确定。如果预计同时处理的客户端连接数量相对稳定,并且希望线程池能够快速响应请求,那么可以将核心线程数设置为能够处理这个常规负载的线程数量。这样,在常规负载下,线程池不需要频繁创建和销毁线程,提高了处理效率。
MAXIMUM_POOL_SIZE
(最大线程数):设置为10,这是线程池能够容纳的最大线程数量。当任务队列已满,并且所有核心线程都在忙碌时,线程池会创建新的线程,直到达到最大线程数。这个值的设置要考虑系统的资源限制,例如CPU核数、内存大小等。如果设置过大,可能会导致系统资源耗尽;如果设置过小,可能无法充分利用系统资源来处理突发的高负载请求。这里设置为10,是在考虑到系统资源的情况下,允许线程池在高负载时适当扩展线程数量来处理更多请求。
KEEP_ALIVE_TIME
(线程存活时间):设置为10秒,当线程池中的线程数量超过核心线程数时,多余的线程在空闲时间达到这个值后会被销毁。这个值的设置要平衡线程销毁带来的开销和系统资源的释放。如果设置过短,可能会导致线程频繁创建和销毁,增加系统开销;如果设置过长,可能会导致空闲线程长时间占用系统资源。这里设置为10秒,在保证系统资源合理利用的同时,避免了线程频繁创建和销毁。
TIME_UNIT
(时间单位):这里设置为TimeUnit.SECONDS
,表示KEEP_ALIVE_TIME
的时间单位是秒。
WORK_QUEUE
(任务队列):使用LinkedBlockingQueue
并设置容量为100,它用于存放等待处理的任务。当核心线程都在忙碌时,新的任务会被放入这个队列中等待处理。队列容量的设置要根据系统的负载情况和内存大小来确定。如果设置过小,可能会导致任务无法及时入队,从而触发线程池创建新的线程;如果设置过大,可能会占用过多内存。这里设置为100,在一定程度上缓冲任务,避免线程池过度扩展线程。