# 13 线程池模式 ## 13.1 完整概念讲解 ### 13.1.1 线程池概念 **线程池(Thread Pool)** 是一种多线程处理模式,预先创建一定数量的线程,将任务放入队列中,由空闲线程从队列中取出任务执行。 **核心优势:** - **减少创建/销毁开销**:线程预先创建,避免频繁的线程创建和销毁 - **提高响应速度**:任务到达时立即有线程处理,无需等待线程创建 - **控制并发数量**:限制同时运行的线程数,避免系统过载 - **统一资源管理**:集中管理线程资源,便于监控和调试 **线程池工作流程:** ``` 任务提交 → 任务队列 → 工作线程取任务 → 执行任务 → 返回等待新任务 ``` ### 13.1.2 线程池架构 **三大核心组件:** ``` ┌─────────────────────────────────────────────────────────┐ │ 线程池管理器 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 工作线程1 │ │ 工作线程2 │ │ 工作线程N │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ └───────────────┼───────────────┘ │ │ │ │ │ ┌─────┴─────┐ │ │ │ 任务队列 │ │ │ └───────────┘ │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ 任务结构体(函数指针+参数) │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` **组件职责:** | 组件 | 职责 | 关键技术 | | ---------- | ------------------ | -------------------------- | | 任务结构体 | 封装任务函数和参数 | 函数指针、void*参数 | | 任务队列 | 存储待执行的任务 | 链表或数组实现 | | 工作线程 | 从队列取任务并执行 | while循环、条件变量 | | 管理线程 | 监控和管理线程池 | 动态调整线程数、销毁线程池 | ### 13.1.3 任务结构体设计 ```c // 任务结构体:封装任务函数和参数 typedef struct { void (*function)(void *arg); // 任务函数指针 void *arg; // 任务参数 } Task; ``` **设计要点:** - **函数指针**:指向要执行的任务函数 - **参数指针**:使用void*实现通用参数传递 - **内存管理**:任务结构体需要动态分配内存 ### 13.1.4 任务队列设计 **链表实现(推荐):** ```c typedef struct TaskNode { Task task; struct TaskNode *next; } TaskNode; typedef struct { TaskNode *head; TaskNode *tail; int count; } TaskQueue; ``` **数组实现(固定大小):** ```c #define MAX_QUEUE_SIZE 100 typedef struct { Task tasks[MAX_QUEUE_SIZE]; int front; int rear; int count; } TaskQueue; ``` **链表 vs 数组:** | 特性 | 链表 | 数组 | | ---------- | ------------ | -------- | | 动态扩展 | 支持 | 不支持 | | 内存开销 | 额外指针开销 | 固定大小 | | 缓存友好性 | 较差 | 较好 | | 实现复杂度 | 较高 | 较低 | ### 13.1.5 线程安全的入队/出队 **互斥锁 + 条件变量实现:** ```c pthread_mutex_t queue_lock; pthread_cond_t queue_not_empty; pthread_cond_t queue_not_full; // 入队操作 void enqueue(Task task) { pthread_mutex_lock(&queue_lock); // 如果队列满,等待 while (queue_full()) { pthread_cond_wait(&queue_not_full, &queue_lock); } // 添加任务到队列 // ... // 通知工作线程有新任务 pthread_cond_signal(&queue_not_empty); pthread_mutex_unlock(&queue_lock); } // 出队操作 Task dequeue() { pthread_mutex_lock(&queue_lock); // 如果队列空,等待 while (queue_empty() && !shutdown) { pthread_cond_wait(&queue_not_empty, &queue_lock); } // 从队列取出任务 // ... // 通知管理线程队列有空间 pthread_cond_signal(&queue_not_full); pthread_mutex_unlock(&queue_lock); return task; } ``` ### 13.1.6 工作线程循环 ```c void *worker_thread(void *arg) { ThreadPool *pool = (ThreadPool *)arg; while (1) { // 从队列获取任务 Task task = dequeue(pool); // 如果收到关闭信号,退出 if (task.function == NULL) { break; } // 执行任务 task.function(task.arg); // 释放任务内存 free(task.arg); } return NULL; } ``` ### 13.1.7 嵌入式应用场景 **网络请求处理:** - Web服务器处理HTTP请求 - TCP服务器处理客户端连接 - UDP服务器处理数据包 **定时任务调度:** - 定时器回调执行 - 周期性任务(如传感器数据采集) - 超时检测和处理 **后台任务处理:** - 日志写入 - 数据同步 - 邮件发送 ## 13.2 核心API/语法 ### 13.2.1 线程池创建函数 ```c #include #include // 线程池结构体 typedef struct { pthread_t *threads; // 工作线程数组 int thread_count; // 工作线程数量 TaskNode *task_head; // 任务队列头指针 TaskNode *task_tail; // 任务队列尾指针 int task_count; // 当前任务数量 pthread_mutex_t queue_lock; // 队列互斥锁 pthread_cond_t not_empty; // 队列非空条件变量 pthread_cond_t not_full; // 队列未满条件变量 int max_queue_size; // 最大队列长度 volatile int shutdown; // 关闭标志 } ThreadPool; // 创建线程池 ThreadPool *thread_pool_create(int thread_count, int max_queue_size); ``` ### 13.2.2 任务提交函数 ```c // 向线程池提交任务 int thread_pool_submit(ThreadPool *pool, void (*function)(void *arg), void *arg); ``` ### 13.2.3 线程池销毁函数 ```c // 销毁线程池 int thread_pool_destroy(ThreadPool *pool); ``` ### 13.2.4 互斥锁和条件变量函数 ```c // 互斥锁 pthread_mutex_init(&mutex, NULL); pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex); pthread_mutex_destroy(&mutex); // 条件变量 pthread_cond_init(&cond, NULL); pthread_cond_wait(&cond, &mutex); // 等待条件 pthread_cond_signal(&cond); // 唤醒一个等待线程 pthread_cond_broadcast(&cond); // 唤醒所有等待线程 pthread_cond_destroy(&cond); ``` ## 13.3 代码示例 ### 13.3.1 完整线程池实现 ```c #include #include #include #include #include #define DEFAULT_THREAD_COUNT 4 #define DEFAULT_MAX_QUEUE_SIZE 100 // 任务结构体 typedef struct { void (*function)(void *arg); // 任务函数指针 void *arg; // 任务参数 } Task; // 任务节点(链表) typedef struct TaskNode { Task task; struct TaskNode *next; } TaskNode; // 线程池结构体 typedef struct { pthread_t *threads; // 工作线程数组 int thread_count; // 工作线程数量 TaskNode *task_head; // 任务队列头指针 TaskNode *task_tail; // 任务队列尾指针 int task_count; // 当前任务数量 pthread_mutex_t queue_lock; // 队列互斥锁 pthread_cond_t not_empty; // 队列非空条件变量 pthread_cond_t not_full; // 队列未满条件变量 int max_queue_size; // 最大队列长度 volatile int shutdown; // 关闭标志 } ThreadPool; // 创建线程池 ThreadPool *thread_pool_create(int thread_count, int max_queue_size) { ThreadPool *pool = (ThreadPool *)malloc(sizeof(ThreadPool)); if (pool == NULL) { return NULL; } // 初始化参数 pool->thread_count = thread_count; pool->max_queue_size = max_queue_size; pool->task_head = NULL; pool->task_tail = NULL; pool->task_count = 0; pool->shutdown = 0; // 初始化同步原语 pthread_mutex_init(&pool->queue_lock, NULL); pthread_cond_init(&pool->not_empty, NULL); pthread_cond_init(&pool->not_full, NULL); // 分配线程数组 pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_count); if (pool->threads == NULL) { free(pool); return NULL; } // 创建工作线程 for (int i = 0; i < thread_count; i++) { if (pthread_create(&pool->threads[i], NULL, worker_thread, pool) != 0) { // 创建失败,清理已创建的线程 pool->shutdown = 1; for (int j = 0; j < i; j++) { pthread_join(pool->threads[j], NULL); } free(pool->threads); pthread_mutex_destroy(&pool->queue_lock); pthread_cond_destroy(&pool->not_empty); pthread_cond_destroy(&pool->not_full); free(pool); return NULL; } } printf("Thread pool created with %d threads\n", thread_count); return pool; } // 工作线程函数 void *worker_thread(void *arg) { ThreadPool *pool = (ThreadPool *)arg; while (1) { // 加锁 pthread_mutex_lock(&pool->queue_lock); // 等待任务或关闭信号 while (pool->task_count == 0 && !pool->shutdown) { pthread_cond_wait(&pool->not_empty, &pool->queue_lock); } // 如果收到关闭信号且队列为空,退出 if (pool->shutdown && pool->task_count == 0) { pthread_mutex_unlock(&pool->queue_lock); break; } // 取出任务 TaskNode *node = pool->task_head; pool->task_head = node->next; if (pool->task_head == NULL) { pool->task_tail = NULL; } pool->task_count--; // 通知管理线程队列有空间 pthread_cond_signal(&pool->not_full); pthread_mutex_unlock(&pool->queue_lock); // 执行任务 node->task.function(node->task.arg); // 释放任务节点 free(node->task.arg); // 释放参数 free(node); // 释放节点 } return NULL; } // 向线程池提交任务 int thread_pool_submit(ThreadPool *pool, void (*function)(void *arg), void *arg) { if (pool == NULL || function == NULL) { return -1; } // 创建任务节点 TaskNode *node = (TaskNode *)malloc(sizeof(TaskNode)); if (node == NULL) { return -1; } node->task.function = function; node->task.arg = arg; node->next = NULL; // 加锁 pthread_mutex_lock(&pool->queue_lock); // 等待队列有空间 while (pool->task_count >= pool->max_queue_size && !pool->shutdown) { pthread_cond_wait(&pool->not_full, &pool->queue_lock); } // 如果已关闭,拒绝新任务 if (pool->shutdown) { pthread_mutex_unlock(&pool->queue_lock); free(node); return -1; } // 添加任务到队列 if (pool->task_tail == NULL) { pool->task_head = node; pool->task_tail = node; } else { pool->task_tail->next = node; pool->task_tail = node; } pool->task_count++; // 通知工作线程有新任务 pthread_cond_signal(&pool->not_empty); pthread_mutex_unlock(&pool->queue_lock); return 0; } // 销毁线程池 int thread_pool_destroy(ThreadPool *pool) { if (pool == NULL) { return -1; } // 设置关闭标志 pthread_mutex_lock(&pool->queue_lock); pool->shutdown = 1; pthread_mutex_unlock(&pool->queue_lock); // 唤醒所有工作线程 pthread_cond_broadcast(&pool->not_empty); // 等待所有工作线程退出 for (int i = 0; i < pool->thread_count; i++) { pthread_join(pool->threads[i], NULL); } // 清理剩余任务 while (pool->task_head != NULL) { TaskNode *node = pool->task_head; pool->task_head = node->next; free(node->task.arg); free(node); } // 释放资源 free(pool->threads); pthread_mutex_destroy(&pool->queue_lock); pthread_cond_destroy(&pool->not_empty); pthread_cond_destroy(&pool->not_full); free(pool); printf("Thread pool destroyed\n"); return 0; } ``` ### 13.3.2 使用示例:任务执行 ```c #include #include #include #include #include // 线程池结构体和函数(同上) // ... (这里省略,实际使用时需要包含完整的线程池实现) // 任务参数结构体 typedef struct { int task_id; char description[64]; } TaskArg; // 示例任务函数1:计算任务 void calculate_task(void *arg) { TaskArg *task_arg = (TaskArg *)arg; printf("[Task %d] Calculating... %s\n", task_arg->task_id, task_arg->description); // 模拟计算 long result = 0; for (int i = 0; i < 1000000; i++) { result += i; } printf("[Task %d] Result: %ld\n", task_arg->task_id, result); } // 示例任务函数2:IO任务 void io_task(void *arg) { TaskArg *task_arg = (TaskArg *)arg; printf("[Task %d] Performing IO... %s\n", task_arg->task_id, task_arg->description); // 模拟IO操作 usleep(100000); // 100ms printf("[Task %d] IO completed\n", task_arg->task_id); } // 示例任务函数3:网络任务 void network_task(void *arg) { TaskArg *task_arg = (TaskArg *)arg; printf("[Task %d] Sending network request... %s\n", task_arg->task_id, task_arg->description); // 模拟网络请求 usleep(200000); // 200ms printf("[Task %d] Network response received\n", task_arg->task_id); } int main() { // 创建线程池:4个工作线程,最大100个任务 ThreadPool *pool = thread_pool_create(4, 100); if (pool == NULL) { fprintf(stderr, "Failed to create thread pool\n"); return 1; } // 提交任务 const char *descriptions[] = { "Heavy computation", "File read/write", "HTTP request", "Database query", "Image processing" }; for (int i = 0; i < 10; i++) { // 分配任务参数 TaskArg *arg = (TaskArg *)malloc(sizeof(TaskArg)); arg->task_id = i; strcpy(arg->description, descriptions[i % 5]); // 根据任务ID选择不同的任务函数 void (*task_func)(void *); switch (i % 3) { case 0: task_func = calculate_task; break; case 1: task_func = io_task; break; case 2: task_func = network_task; break; default: task_func = calculate_task; } // 提交任务 if (thread_pool_submit(pool, task_func, arg) != 0) { fprintf(stderr, "Failed to submit task %d\n", i); free(arg); } else { printf("Submitted task %d\n", i); } usleep(50000); // 50ms间隔提交 } // 等待任务完成 sleep(5); // 销毁线程池 thread_pool_destroy(pool); return 0; } ``` ### 13.3.3 编译完整示例 将线程池实现和使用示例保存为`threadpool_demo.c`,然后编译运行: ```bash gcc -pthread -o threadpool_demo threadpool_demo.c ./threadpool_demo ``` ### 13.3.4 嵌入式场景:网络请求处理 ```c #include #include #include #include #include // 线程池结构体和函数(同上) // ... (这里省略,实际使用时需要包含完整的线程池实现) // HTTP请求结构体 typedef struct { int client_fd; char method[16]; char path[256]; char *body; } HttpRequest; // 处理HTTP请求的任务函数 void handle_http_request(void *arg) { HttpRequest *req = (HttpRequest *)arg; printf("[HTTP] Handling request: %s %s\n", req->method, req->path); // 模拟处理时间 usleep(50000); // 50ms // 构建响应 char response[1024]; snprintf(response, sizeof(response), "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n" "" "

Hello from Thread Pool!

" "

Request: %s %s

" "", req->method, req->path); // 发送响应(模拟) printf("[HTTP] Response sent: %zu bytes\n", strlen(response)); // 关闭连接(模拟) close(req->client_fd); // 释放请求体 if (req->body) { free(req->body); } free(req); } // 模拟TCP服务器 void simulate_tcp_server(void) { printf("=== TCP Server Simulation ===\n"); // 创建线程池:4个工作线程,最大50个连接 ThreadPool *pool = thread_pool_create(4, 50); if (pool == NULL) { fprintf(stderr, "Failed to create thread pool\n"); return; } // 模拟接收10个客户端连接 for (int i = 0; i < 10; i++) { HttpRequest *req = (HttpRequest *)malloc(sizeof(HttpRequest)); req->client_fd = 100 + i; // 模拟文件描述符 strcpy(req->method, "GET"); snprintf(req->path, sizeof(req->path), "/page%d.html", i); req->body = NULL; // 提交任务到线程池 if (thread_pool_submit(pool, handle_http_request, req) != 0) { fprintf(stderr, "Failed to submit HTTP request %d\n", i); free(req); } else { printf("Accepted connection %d\n", i); } usleep(10000); // 10ms间隔 } // 等待所有请求处理完成 sleep(3); // 销毁线程池 thread_pool_destroy(pool); } int main() { simulate_tcp_server(); return 0; } ``` **编译运行:** ```bash gcc -pthread -o http_server http_server.c ./http_server ``` ### 13.3.5 嵌入式场景:定时任务调度 ```c #include #include #include #include #include // 线程池结构体和函数(同上) // ... (这里省略,实际使用时需要包含完整的线程池实现) // 定时任务结构体 typedef struct { int task_id; int interval_ms; // 执行间隔(毫秒) int count; // 执行次数 void (*task_func)(void *arg); void *arg; } TimerTask; // 定时任务执行函数 void timer_task_executor(void *arg) { TimerTask *timer = (TimerTask *)arg; printf("[Timer %d] Starting, interval=%dms, count=%d\n", timer->task_id, timer->interval_ms, timer->count); for (int i = 0; i < timer->count; i++) { usleep(timer->interval_ms * 1000); // 转换为微秒 printf("[Timer %d] Executing task #%d\n", timer->task_id, i + 1); // 执行实际任务 if (timer->task_func) { timer->task_func(timer->arg); } } printf("[Timer %d] Completed\n", timer->task_id); free(timer->arg); free(timer); } // 示例定时任务:传感器数据采集 void sensor_data_collection(void *arg) { int sensor_id = *(int *)arg; int value = rand() % 100; printf("[Sensor %d] Value: %d\n", sensor_id, value); } // 示例定时任务:心跳检测 void heartbeat_check(void *arg) { int server_id = *(int *)arg; printf("[Heartbeat] Server %d is alive\n", server_id); } // 模拟定时任务调度器 void simulate_timer_scheduler(void) { printf("=== Timer Task Scheduler Simulation ===\n"); // 创建线程池:2个工作线程,最大20个任务 ThreadPool *pool = thread_pool_create(2, 20); if (pool == NULL) { fprintf(stderr, "Failed to create thread pool\n"); return; } // 创建定时任务 TimerTask *tasks[5]; // 任务1:每100ms采集传感器数据,执行10次 tasks[0] = (TimerTask *)malloc(sizeof(TimerTask)); tasks[0]->task_id = 1; tasks[0]->interval_ms = 100; tasks[0]->count = 10; tasks[0]->task_func = sensor_data_collection; tasks[0]->arg = malloc(sizeof(int)); *(int *)tasks[0]->arg = 1; // 任务2:每200ms采集另一个传感器数据,执行5次 tasks[1] = (TimerTask *)malloc(sizeof(TimerTask)); tasks[1]->task_id = 2; tasks[1]->interval_ms = 200; tasks[1]->count = 5; tasks[1]->task_func = sensor_data_collection; tasks[1]->arg = malloc(sizeof(int)); *(int *)tasks[1]->arg = 2; // 任务3:每500ms发送心跳,执行3次 tasks[2] = (TimerTask *)malloc(sizeof(TimerTask)); tasks[2]->task_id = 3; tasks[2]->interval_ms = 500; tasks[2]->count = 3; tasks[2]->task_func = heartbeat_check; tasks[2]->arg = malloc(sizeof(int)); *(int *)tasks[2]->arg = 1; // 提交定时任务到线程池 for (int i = 0; i < 3; i++) { if (thread_pool_submit(pool, timer_task_executor, tasks[i]) != 0) { fprintf(stderr, "Failed to submit timer task %d\n", i + 1); free(tasks[i]->arg); free(tasks[i]); } else { printf("Timer task %d submitted\n", i + 1); } } // 等待定时任务完成 sleep(5); // 销毁线程池 thread_pool_destroy(pool); } int main() { srand(time(NULL)); simulate_timer_scheduler(); return 0; } ``` **编译运行:** ```bash gcc -pthread -o timer_scheduler timer_scheduler.c ./timer_scheduler ``` ## 13.4 注意事项与易错点 ### 13.4.1 线程池创建注意事项 | 问题 | 描述 | 解决方案 | | ------------------ | ------------------------------ | ------------------------------------ | | 线程数设置不合理 | 过多线程导致上下文切换开销 | 根据CPU核心数设置,通常为核心数的2倍 | | 队列大小不合理 | 过小导致任务丢失,过大浪费内存 | 根据任务特点和内存限制设置 | | 内存分配失败 | malloc失败导致创建失败 | 检查返回值,失败时清理资源 | | 同步原语初始化失败 | mutex/cond初始化失败 | 检查返回值,失败时清理资源 | ### 13.4.2 任务提交注意事项 | 问题 | 描述 | 解决方案 | | ---------------- | ------------------ | ------------------------ | | 任务参数内存泄漏 | 提交后忘记释放参数 | 任务执行完成后释放参数 | | 空指针参数 | 传入NULL作为参数 | 检查参数有效性 | | 任务函数为空 | function指针为NULL | 检查函数指针有效性 | | 队列满时阻塞 | 提交任务时队列满 | 设置超时或使用非阻塞模式 | ### 13.4.3 线程池销毁注意事项 | 问题 | 描述 | 解决方案 | | -------------- | ---------------------- | ---------------------------- | | 未设置关闭标志 | 工作线程无法退出 | 先设置shutdown标志 | | 未唤醒工作线程 | 工作线程在等待条件变量 | 使用broadcast唤醒所有线程 | | 未等待线程退出 | 资源未完全释放 | 使用pthread_join等待所有线程 | | 未清理剩余任务 | 任务内存泄漏 | 销毁时清理队列中的所有任务 | ### 13.4.4 常见错误代码示例 ```c // 错误示例1:任务参数内存泄漏 void bad_task(void *arg) { char *data = (char *)arg; printf("Data: %s\n", data); // 错误:没有释放data } // 正确做法 void good_task(void *arg) { char *data = (char *)arg; printf("Data: %s\n", data); free(data); // 释放参数 } // 错误示例2:未检查线程池创建返回值 ThreadPool *pool = thread_pool_create(4, 100); // 如果pool为NULL,后续操作会崩溃 // 正确做法 ThreadPool *pool = thread_pool_create(4, 100); if (pool == NULL) { fprintf(stderr, "Failed to create thread pool\n"); return 1; } // 错误示例3:销毁时未等待线程退出 pool->shutdown = 1; free(pool->threads); // 线程可能还在运行 // 正确做法:先pthread_join,再释放内存 ``` ### 13.4.5 嵌入式场景注意事项 **资源限制:** - 嵌入式系统内存有限,线程池大小受限 - 线程栈大小需要根据任务调整 - 避免使用动态内存分配(如可能) **实时性考虑:** - 线程池不适合硬实时任务 - 任务执行时间不确定 - 需要评估最坏情况下的延迟 **错误处理:** - 任务执行失败需要重试机制 - 线程异常退出需要重新创建 - 需要健康监控和故障恢复 ## 13.5 面试要点 ### Q1: 什么是线程池?为什么需要线程池? **答:** - **定义**:线程池是一种多线程处理模式,预先创建一定数量的线程,将任务放入队列中执行 - **优势**: 1. 减少线程创建/销毁开销 2. 提高响应速度(任务到达立即处理) 3. 控制并发数量,避免系统过载 4. 统一资源管理,便于监控 ### Q2: 线程池的核心组件有哪些? **答:** - **任务结构体**:封装任务函数和参数(函数指针+void*参数) - **任务队列**:存储待执行的任务(链表或数组实现) - **工作线程**:从队列取任务并执行(while循环+条件变量) - **管理线程**:监控和管理线程池(动态调整、销毁) ### Q3: 如何实现线程安全的任务队列? **答:** - 使用**互斥锁**保护队列的读写操作 - 使用**条件变量**实现线程同步: - `not_empty`:队列非空时唤醒工作线程 - `not_full`:队列未满时唤醒管理线程 - 入队/出队操作需要在加锁状态下进行 ### Q4: 工作线程的工作流程是什么? **答:** ``` 1. 加锁 2. 检查队列是否为空且未关闭 - 是:等待条件变量(not_empty) - 否:继续 3. 取出任务节点 4. 队列计数减1 5. 通知队列有空间(not_full) 6. 解锁 7. 执行任务函数 8. 释放任务内存 9. 返回步骤1 ``` ### Q5: 如何处理线程池中的任务失败? **答:** - **任务层面**:在任务函数中添加错误处理和重试逻辑 - **线程层面**:工作线程捕获异常,防止线程退出 - **监控层面**:记录失败任务,通知管理员 - **超时机制**:为任务设置超时,避免长时间阻塞 ### Q6: 线程池在嵌入式系统中的应用场景有哪些? **答:** - **网络请求处理**:Web服务器、TCP/UDP服务器 - **定时任务调度**:传感器数据采集、心跳检测 - **后台任务处理**:日志写入、数据同步 - **多协议处理**:同时处理多种通信协议 - **资源受限场景**:避免频繁创建/销毁线程 ### Q7: 如何优化线程池性能? **答:** - **线程数优化**:根据CPU核心数和任务类型设置 - CPU密集型:核心数+1 - IO密集型:核心数×2 - **队列优化**:根据任务特点选择链表或数组 - **任务粒度**:避免任务过大或过小 - **缓存友好**:减少缓存未命中 - **减少锁竞争**:使用无锁队列(高级优化) ### Q8: 线程池的常见设计模式有哪些? **答:** - **固定大小线程池**:线程数固定,任务排队执行 - **可缓存线程池**:任务多时创建新线程,空闲时回收 - **定时线程池**:支持定时和周期性任务 - **单线程线程池**:单个工作线程,保证任务顺序执行 - **工作窃取线程池**:空闲线程从其他线程队列窃取任务(ForkJoinPool)