實現解耦爲:任務隊列管理和線程管理
文分三部分:任務控制、線程池控制及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);
}
}