实现解耦为:任务队列管理和线程管理
文分三部分:任务控制、线程池控制及Demo
类图:
类变量:
private int capacity; // 任务队列容量
private long timeout; // 任务超时时间(ms)
private HashMap tasks;// task容器
private ArrayList readyTasks; // 准备就绪的待处理任务
1、任务控制部分
createTaskManager:创建任务管理器(静态)
/**
* 创建TaskManager
*
* @param name
* Task名称
* @param capacity
* Task队列容量
* @param timeout
* 任务超时时间
* @param processor
* 任务处理器
* @param processorNum
* 处理线程数
* @return TaskManager实例
*/
public static TaskManager createTaskManager(String name, int capacity, long timeout, TaskProcessor processor, int processorNum) {
TaskManager mgt = null;
if (capacity >=0 && timeout >=0 && processor != null && processorNum > 0) {
// 初始化管理器
mgt = new TaskManager(capacity, timeout);
mgt.start(name, processor, processorNum);
}
return mgt;
}
构造Task管理器:
注:包含一个Timer 定时延时任务处理器,用于任务超时处理
protected TaskManager(int capacity, long timeout ) {
this.capacity = capacity;
this.timeout = timeout;
tasks = new HashMap();
readyTasks = new ArrayList();
// 任务定时器(超时任务处理)
timer = new Timer(true);
}
Task管理器启动mgt.start() :初始化线程控制器并启动分配线程处理任务
private void start(String name, TaskProcessor processor, int processorNum) {
ProcessorControllor control = new ProcessorControllor(name, processorNum, processor, this);
control.start();
}
线程控制器的构造:
public ProcessorControllor(String name, int processorNum, TaskProcessor processor, TaskManager manager){
super(name);
this.taskManager = manager;
this.processorNum = processorNum;
this.processor = processor;
this.setDaemon(true);
// 线程池 创建指定数目的Thread、调度空闲线程
pool = new ThreadPool(name, this.processorNum);
// 负责处理任务
threadPoolTask = new ThreadPoolTask(this.processor);
}
2、线程池控制部分
线程池初始化:
public ThreadPool(String name, int maxNum)
{
if (maxNum > 0)
{
threads = new WorkThread[maxNum];
for(int i = 0; i < maxNum; i++)
{
threads[i] = new WorkThread(name, i);
threads[i].start();
}
statistic_start_time = System.currentTimeMillis();
TraceManager.TrDebug(null, "ThreadPool:" + name + " " + maxNum + " threads created.");
}
}
工作线程:WorkThread
做初始化,线程启动后处于阻塞状态,等待线程池抓取,空闲时交由任务处理
private class WorkThread extends Thread
{
// 工作线程在处理的任务task
private Task task = null;
private TaskParameter parameter = null;
public WorkThread(String name, int index)
{
super("ThreadPool_" + name + "_" + index);
}
public void run()
{
TraceManager.TrDebug(null, Thread.currentThread().getName() + " started!");
while(true)
{
try
{
synchronized(this)
{
// 阻塞 直到线程空闲时将任务加入到task
while(task == null)
{
this.wait();
}
}
toWork();
synchronized(this)
{
task = null;
parameter = null;
}
workThreadDone();
}
catch(InterruptedException ex)
{
TraceManager.TrException(null, ex);
}
catch(Exception ex)
{
TraceManager.TrException(null, ex);
}
}
}
}
线程Processor任务器:
class ThreadPoolTask implements ThreadTask {
TaskProcessor processor;
public ThreadPoolTask(TaskProcessor processor) {
this.processor = processor;
}
public void run(TaskParameter parameter) {
try {
Task task = (Task)parameter;
if (task.isTimeout()) {
processor.timeout(task);
}else {
processor.process(task);
}
}catch(Exception ex){
CAP.trException(ex);
}
}
}
线程池分配线程处理任务:
ProcessorControllor.run()
public void run() {
CAP.trDebug(this.getName() + " started.");
Task task = null;
while (true) {
// 抓取taskManager中准备就绪的任务
task = taskManager.processorControllorWait();
if (task != null) {
// 获取空闲工作线程,唤醒线程
pool.getThread(threadPoolTask, task, true);
}
}
}
从Task管理器中移除就绪任务
TaskManager.processorControllorWait():
protected Task processorControllorWait() {
Task task = null;
Object key = null;
synchronized(readyTasks) {
while (readyTasks.size() == 0) {
try {
readyTasks.wait();
}catch(Exception ex){
CAP.trException(ex);
}
}
key = readyTasks.remove(0);
}
task = this.removeTask(key);
return task;
}
将就绪任务交由空闲WorkThread处理:
ThreadPool.getThread()
public int getThread(Task task, TaskParameter parameter, boolean blocked)
{
if(task == null)
{
return -1;
}
if (!blocked)
{
return getThread(task, parameter);
}
synchronized(this)
{
boolean over = false;
long startTime = System.currentTimeMillis();
long elapsedTime = 0;
while (!over)
{
for(int i = 0; i < threads.length; i++)
{
// 获得空闲线程
if (threads[i].isIdle(task, parameter))
{
return i;
}
}
try
{
// to block the calling thread.
elapsedTime = System.currentTimeMillis() - startTime;
if (elapsedTime < MAX_WAIT_TIME)
{
TraceManager.TrDebug(null,
Thread.currentThread().getName() + " to wait.");
this.wait(MAX_WAIT_TIME - elapsedTime);
}
else
{
over = true;
TraceManager.TrDebug(null,
Thread.currentThread().getName() +
" waiting too long and will give up waiting.");
}
TraceManager.TrDebug(null,
Thread.currentThread().getName() +
" waked up!");
}
catch(InterruptedException ex)
{
over = true;
TraceManager.TrException(null, ex);
}
}
}
return -1;
}
WorkThread唤醒,由Porcessor处理任务:
WorkThread.toWork()
private void toWork()
{
TraceManager.TrDebug(null,
Thread.currentThread().getName() + ": to run user task.");
try
{
this.task.run(parameter);
}
catch(Throwable ex)
{
TraceManager.TrException(null, ex);;
}
TraceManager.TrDebug(null,
Thread.currentThread().getName() + ": user task done.");
}
以上完成了Task队列、线程池的构造,现在可以添加任务到Task队列:
TaskManager.addTask
public int addTask(Task task, int priority, int taskStatus) {
int rst = ERROR_INVALID_PARAMETER;
if (task == null) {
return rst;
}
Object taskKey = task.getPrimaryKey();
if (taskKey == null) {
return rst;
}
if (priority != HIGH_PRIORITY && priority != LOW_PRIORITY) {
return rst;
}
synchronized(tasks) {
if (tasks.get(taskKey) != null) {
CAP.trError("Queue key is duplicated.");
return ERROR_KEY_DUPLICATED;
}
if (capacity > 0) {
int size = tasks.size();
if (size >= capacity) {
CAP.trError("Queue capacity exceeded and one task rejected!");
return ERROR_CAPACITY_EXCEEDED;
}
CAP.trDebug("Total tasks:" + size + "/" + capacity);
}
TaskContainer container = new TaskContainer(task);
tasks.put(taskKey, container);
timer.schedule(container, timeout);
}
if (taskStatus == Task.STATUS_READY) {
synchronized(readyTasks) {
if (priority == HIGH_PRIORITY ) {
readyTasks.add(0, taskKey);
}else {
readyTasks.add(taskKey);
}
readyTasks.notifyAll();
}
}
rst = OK;
return rst;
}
3、Demo
自定义Task,实现抽象方法getPrimaryKey()
PrimaryKey为task容器的唯一主键
public class MyTask extends Task {
@Override
public Object getPrimaryKey() {
return System.currentTimeMillis();
}
}
自定义task 处理类,实现TaskProcessor接口
public class MyTaskProcessor implements TaskProcessor {
public void process(Task task) {
System.out.println(task.getPrimaryKey() + " processing...");
}
public void timeout(Task task) {
System.out.println(task.getPrimaryKey() + " timeout...");
}
创建任务管理器和添加任务:
public class MyManager {
public static void main(String[] args) {
TaskManager mgt = TaskManager.createTaskManager("MyManager", 5, 10 * 1000, new MyTaskProcessor(), 2);
mgt.addTask(new MyTask(), TaskManager.HIGH_PRIORITY, Task.STATUS_READY);
}
}