【梳理】多線程任務管理器的實現

實現解耦爲:任務隊列管理和線程管理

文分三部分:任務控制、線程池控制及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);
		
	}
}

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章