其实第9篇已经写了WorkPool 工作池 ,了解workPool里面源码,以及使用LinkedBlockingQueue源码,也算是对blocking队列熟悉, 这节熟悉WorkPool调用方ConsumerWorkService ,顾名思义就是消费者的工作服务,因为write一般是实时写操作,消费需要多个线程,顺便透露一下ConsumerWorkService还有一个ConsumerDispatcher 分发器,不同消息做不同分发,进入正题
- ConsumerWorkService是一个final类,其实我们在定义类尽量约束更紧能用private,绝对不能用public, 同时类也是一样,如果明确这个类无法继承就定义final类
1、成员变量和常量
类型 | 字段 | 默认值 | 含义 |
---|---|---|---|
int | MAX_RUNNABLE_BLOCK_SIZE | 16 | 最大阻塞线程数 |
int | DEFAULT_NUM_THREADS | 当前机器处理器数 * 2 | 默认线程数量 |
ExecutorService | executor | 线程执行器 | |
boolean | privateExecutor | false | 是否为私有执行器 |
WorkPool<Channel, Runnable> | workPool | 工作池 | |
int | shutdownTimeout | false | 关闭超时间 |
2、构造方法
方法名 | 值 | 描述 |
---|---|---|
ConsumerWorkService(executor, threadFactory, queueingTimeout shutdownTimeout) | privateExecutor =(executor=null); 如果没有传executor就是要固定DEFAULT_NUM_THREADS线程池 | |
ConsumerWorkService(executor, threadFactory, shutdownTimeout) | 默认队列不超时 | |
3、普通方法
方法名 | 描述 | 图示 |
---|---|---|
void shutdown() | 清除workPool所有任务,同时确实是否关闭executor执行器,如果默认创建就直接shutdown,如果外面传过来就不处理 | |
void stopWork(channel) | 关闭某个channel的任务 | |
void registerKey(channel) | 注册某个channel,没有初始任务 | |
void setUnlimited(channel unlimited) | unlimited==true所有chanel的LinkedBlockingQueue容量变成 Integer.MAX, 否则所有容量变成1000 ( 这个可能有问题) | |
void addWork(channel runnable) | 向workpool 中添加任务,且里面是Runnable对象,可以作为开启线程使用 | 1 |
3.1、图示
- 总结
- 向workpool添加工作任务
- 添加成功之后线程执行器就执行从workpool拉取准备好的通道的任务
- 一次默认取16条,如果有准备好的,就遍历每个任务
- 执行Runnable的run方法,不会创建新线程
- 执行完这批次,然后再去workpool是否还有准备好任务,如果还有继续 3步骤
4、总结
- ConsumerWorkService就是对于WorkPool应用
- 主要是添加任务以及开启线程executor 执行workPool准备好的任务。