线程池的种类以及使用场景

线程池

线程池的种类以及使用场景

CachedThreadPool 

这类线程池的特点就是里面没有核心线程,全是非核心线程,其maximumPoolSize设置为Integer.MAX_VALUE,线程可以无限创建,当线程池中的线程都处于活动状态的时候,线程池会创建新的线程来处理新任务,否则会用空闲的线程来处理新任务,这类线程池的空闲线程都是有超时机制的,keepAliveTime在这里是有效的,时长为60秒,超过60秒的空闲线程就会被回收,当线程池都处于闲置状态时,线程池中的线程都会因为超时而被回收,所以几乎不会占用什么系统资源。任务队列采用的是SynchronousQueue,这个队列是无法插入任务的,一有任务立即执行,所以CachedThreadPool比较适合任务量大但耗时少的任务。

FixedThreadPool

这类线程池的特点就是里面全是核心线程,没有非核心线程,也没有超时机制,任务大小也是没有限制的,数量固定,即使是空闲状态,线程不会被回收,除非线程池被关闭,从构造方法也可以看出来,只有两个参数,一个是指定的核心线程数,一个是线程工厂,keepAliveTime无效。任务队列采用了无界的阻塞队列LinkedBlockingQueue,执行execute方法的时候,运行的线程没有达到corePoolSize就创建核心线程执行任务,否则就阻塞在任务队列中,有空闲线程的时候去取任务执行。由于该线程池线程数固定,且不被回收,线程与线程池的生命周期同步,所以适用于任务量比较固定但耗时长的任务。

ScheduledThreadPool

这类线程池核心线程数量是固定的,好像和FixThreadPool有点像,但是它的非核心线程是没有限制的,并且非核心线程一闲置就会被回收,keepAliveTime同样无效,因为核心线程是不会回收的,当运行的线程数没有达到corePoolSize的时候,就新建线程去DelayedWorkQueue中取ScheduledFutureTask然后才去执行任务,否则就把任务添加到DelayedWorkQueue,DelayedWorkQueue会将任务排序,按新建一个非核心线程顺序执行,执行完线程就回收,然后循环。任务队列采用的DelayedWorkQueue是个无界的队列,延时执行队列任务。综合来说,这类线程池适用于执行定时任务和具体固定周期的重复任务。

SingleThreadPool
这类线程池顾名思义就是一个只有一个核心线程的线程池,从构造方法来看,它可以单独执行,也可以与周期线程池结合用。其任务队列是LinkedBlockingQueue,这是个无界的阻塞队列,因为线程池里只有一个线程,就确保所有的任务都在同一个线程中顺序执行,这样就不需要处理线程同步的问题。这类线程池适用于多个任务顺序执行的场景。

线程池的实现:线程数量固定的线程池

  1 /*=============================================================== 
  2 *   Copyright (CPP) . All rights reserved.")
  3 *   文件名称: 
  4 *   创 建 者:罗毅
  5 *   创建日期:
  6 *   描    述:自主实现线程池 
  7 *")
  8 ================================================================*/
  9 #include <iostream>
 10 #include <queue>
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <unistd.h>
 14 #include <time.h>
 15 #include <pthread.h>
 16 
 17 typedef bool (*task_callback)(int data);
 18 bool deal_data(int data)
 19 {
 20     srand(time(NULL));
 21     int n = rand()%5;
 22     printf("thread:%p----deal data:%d---sleep %d sec\n",
 23             pthread_self(), data, n);
 24     sleep(n);
 25     return true;
 26 }
 27 class Task
 28 {
 29     public:
 30         Task(){
 31         }
 32         ~Task(){
 33         }
 34     public:
 35         void SetTask(int data, task_callback handle){
 36             _data = data;
 37             _handle = handle;
 38         }
 39         bool Run(){
 40             return _handle(_data);
 41         }
 42     private:
 43         int _data;//任务处理要处理的数据
 44         task_callback _handle;//任务的处理方法
 45 };
 46 
 47 #define MAX_THR 5
 48 #define MAX_QUE 10
 49 class ThreadPool
 50 {
 51     public:
 52         ThreadPool(){
 53         }
 54         ~ThreadPool(){
 55             pthread_mutex_destroy(&_mutex);
 56             pthread_cond_destroy(&_cond_con);
 57             pthread_cond_destroy(&_cond_pro);
 58         }
 59         bool ThreadInit(int max_thr = MAX_THR, int max_que = MAX_QUE) {
 60             //实现变量初始化和线程创建
 61             _quit_flag = false;
 62             _max_thr = max_thr;
 63             _cur_thr = max_thr;
 64             _capacity = max_que;
 65             pthread_mutex_init(&_mutex, NULL);
 66             pthread_cond_init(&_cond_con, NULL);
 67             pthread_cond_init(&_cond_pro, NULL);
 68             int ret;
 69             pthread_t tid;
 70             for (int i = 0; i < _max_thr; i++) {
 71                 ret=pthread_create(&tid, NULL, thr_start, (void*)this);
 72                 if (ret != 0) {
 73                     printf("thread create error\n");
 74                     return false;
 75                 }
 76                 pthread_detach(tid);
 77             }
 78             return true;
 79         }
 80         bool PushTask(Task &task){
 81             //向任务队列中添加任务
 82             if (_quit_flag == true){
 83                 return false;
 84             }
 85             QueueLock();
 86             while (QueueIsFull()){
 87                 ProWait();
 88             }
 89             _queue.push(task);
 90             ConWakeUp();
 91             QueueUnLock();
 92             return true;
 93         }
 94         void ThreadQuit() {
 95             //线程池退出
 96             if (_quit_flag != true) {
 97                 _quit_flag = true;
 98             }
 99             while(_cur_thr > 0) {
100                 ConWakeUpAll();
101                 sleep(1);
102             }
103             return;
104         }
105     private:
106         void QueueLock(){
107             pthread_mutex_lock(&_mutex);
108         }
109         void QueueUnLock(){
110             pthread_mutex_unlock(&_mutex);
111         }
112         void ConWait(){
113             //进入ConWait表示消费者这时候没有数据待处理,则解锁退出
114             if (_quit_flag == true) {
115                 pthread_mutex_unlock(&_mutex);
116                 printf("thread:%p exit\n", pthread_self());
117                 _cur_thr--;
118                 pthread_exit(NULL);
119             }
120             pthread_cond_wait(&_cond_con, &_mutex);
121         }
122         void ConWakeUp(){
123             pthread_cond_signal(&_cond_con);
124         }
125         void ConWakeUpAll(){
126             printf("wake up all\n");
127             pthread_cond_broadcast(&_cond_con);
128         }
129         void ProWait(){
130             pthread_cond_wait(&_cond_pro, &_mutex);
131         }
132         void ProWakeUp(){
133             pthread_cond_signal(&_cond_pro);
134         }
135         bool QueueIsFull(){
136             return (_capacity == _queue.size());
137         }
138         bool QueueIsEmpty(){
139             return _queue.empty();
140         }
141         void PopTask(Task *task){
142             *task = _queue.front();
143             _queue.pop();
144         }
145         static void *thr_start(void *arg){
146             ThreadPool *pool = (ThreadPool*)arg;
147             while(1){
148                 pool->QueueLock();
149                 while(pool->QueueIsEmpty()){
150                     pool->ConWait();
151                 }
152                 Task task;
153                 pool->PopTask(&task);
154                 pool->ProWakeUp();
155                 pool->QueueUnLock();
156                 //任务处理要放到解锁之外,否则任务处理时间过程导致其它线
157                 //程阻塞
158                 task.Run();
159             }
160             return NULL;
161         }
162     private:
163         int _max_thr;//线程池中最大线程数量
164         int _cur_thr;//线程池中当前线程数量
165         int _quit_flag;//线程池中线程退出标志
166         int _capacity;//队列的最大节点数目
167         std::queue<Task> _queue;//任务队列
168         pthread_mutex_t _mutex;//
169         pthread_cond_t _cond_pro;//生产者
170         pthread_cond_t _cond_con;//消费者
171 };
172 
173 int main (int argc, char *argv[])
174 {
175     ThreadPool pool;
176 
177     pool.ThreadInit();
178     Task task[10];
179     for (int i = 0; i < 10; i++) {
180         task[i].SetTask(i, deal_data);
181         pool.PushTask(task[i]);
182     }
183     pool.ThreadQuit();
184     return 0;
185 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 一堆有固定数量/有最大数量限制的线程+任务队列-----------用于并发处理任务请求
  • 线程池避免了大量频繁的线程创建销毁所来的成本
  • 线程池避免峰值压力带来的瞬间大量线程被创建资源耗尽,程序奔溃的危险
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值