日常編碼中,我們常需要為各種業(yè)務(wù)進(jìn)行建模,為工廠中的任務(wù)調(diào)度建模就很有意思的,它的主要流程是基本是這樣:
1.調(diào)度員將工件圖紙交付給工人,這是任務(wù)的下達(dá).
2.工人工作,完成工件,這是任務(wù)的進(jìn)行過程.
3.工件完成后,工人將圖紙和工件返還給調(diào)度員,或者到了確定的時間后由調(diào)度員去取.這是任務(wù)的完成.
4.重復(fù)上述三個步驟.
在這個流程中,還存在一些特征:
1.工人可以有多項任務(wù),但他在一個時間只能做一個活,具體做那個由任務(wù)的優(yōu)先級確定.
2.任務(wù)完成后要讓調(diào)度員知道,現(xiàn)實中是工人來找調(diào)度員或者調(diào)度員找工人來實現(xiàn)的.一般來說調(diào)度員找工人的情況居多.
從上述情況分析,我們需要任務(wù),工人,調(diào)度員三個類來完成建模,另外為了方便任務(wù)的存儲和管理,還需要一個任務(wù)串類來輔助.
首先看任務(wù)類,除了Id,name這樣的常規(guī)屬性外,它應(yīng)該具有下面的成員:
1.完成所需要的總工時數(shù).
2.已經(jīng)完成的工時數(shù),它和總工時數(shù)的比值就是完成比例.
3.優(yōu)先級.
4.任務(wù)接受者,也就是工人.
5.任務(wù)發(fā)布者,也就是調(diào)度員.
它還應(yīng)該具有一個重要函數(shù),這個函數(shù)應(yīng)該是定時被執(zhí)行的,執(zhí)行時先增加已經(jīng)完成的工時數(shù),然后看是否完成,是則把自己從任務(wù)接受者的待完成任務(wù)鏈表中刪除,再添加到任務(wù)發(fā)布者的已完成任務(wù)鏈表中去.
具體代碼如下:
package com.sitinspring.taskmanagement.domain;

import com.sitinspring.taskmanagement.util.IdUtil;


public class Task implements Comparable
{
private String id;

private String name;

// 完成需消耗的工時數(shù)
private int manHour;

// 已經(jīng)完成的工時數(shù)
private int completed;

// 優(yōu)先級
private int priority;

// 接受任務(wù)者
private Worker worker;

// 發(fā)布任務(wù)者
private Attemper attemper;


public Task(String name, int manHour)
{
this(name, manHour, 0);
}


public Task(String name, int manHour, int priority)
{
id = IdUtil.generateId();
this.name = name;
this.manHour = manHour;
this.priority = priority;
this.completed = 0;
}

// 任務(wù)是否完成

public boolean isCompleted()
{
return completed >= manHour;
}

// 添加完成度

public void addCompleted(int n)
{
completed += n;


if (isCompleted())
{
completed = manHour;


if (worker != null)
{
// 完成后讓工人把自己從任務(wù)列表中刪除
worker.removeTask(this);
}


if (attemper != null)
{
// 完成后把任務(wù)添加到調(diào)度員(任務(wù)發(fā)送者)的完成任務(wù)鏈表
attemper.addCompletedTask(this);
}
}
}


public int compareTo(Object obj)
{
Task another = (Task) obj;
return (another.priority) - this.priority;
}


public String toString()
{
return "任務(wù)名:" + name + " 工人名:" + worker.getName() + " 完成度:" + completed
* 100 / manHour + "%";
}


public int getCompleted()
{
return completed;
}


public void setCompleted(int completed)
{
this.completed = completed;
}


public int getManHour()
{
return manHour;
}


public void setManHour(int manHour)
{
this.manHour = manHour;
}


public String getName()
{
return name;
}


public void setName(String name)
{
this.name = name;
}


public String getId()
{
return id;
}


public int getPriority()
{
return priority;
}


public void setPriority(int priority)
{
this.priority = priority;
}


public Worker getWorker()
{
return worker;
}


public void setWorker(Worker worker)
{
this.worker = worker;
}


public Attemper getAttemper()
{
return attemper;
}


public void setAttemper(Attemper attemper)
{
this.attemper = attemper;
}
}
其次再來看任務(wù)串類,它用于管理多個任務(wù),自然它必定具有一個鏈表成員,類中大部分函數(shù)都是圍繞這個成員設(shè)計的,另外考慮到工人需要取得最優(yōu)先的任務(wù),鏈表需要按任務(wù)的優(yōu)先級排序,然后做一個函數(shù)用于取得最開頭的任務(wù)即優(yōu)先級最高的任務(wù).isCompleted函數(shù)用于判斷所有任務(wù)是否完成.
代碼如下:
package com.sitinspring.taskmanagement.domain;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;


public class TaskBunch
{
// 任務(wù)鏈表
private List<Task> tasks;

public TaskBunch()
{
tasks=new LinkedList<Task>();
}
// 取得最優(yōu)先任務(wù)

public Task getTopTask()
{
return tasks.get(0);
}
// 取得任務(wù)個數(shù)

public int getSize()
{
return tasks.size();
}
// 判斷是否完成

public boolean isCompleted()
{

for(Task task:tasks)
{

if(task.isCompleted()==false)
{
return false;
}
}
return true;
}
// 添加任務(wù)

public void addTask(Task task)
{
tasks.add(task);
Collections.sort(tasks);
}
// 刪除任務(wù)

public void removeTask(Task task)
{
tasks.remove(task);
}
}
接下來是工人類,它有一個任務(wù)串成員用于存儲待完成任務(wù),由于它需要定時執(zhí)行任務(wù),因此需要實現(xiàn)Runnable接口,在run函數(shù)中處理任務(wù),另外再做一個doWork()讓線程工作起來.工作時首先取得待完成任務(wù)鏈表中的優(yōu)先級最高的任務(wù),執(zhí)行任務(wù)中的addCompleted方法,如果待完成任務(wù)一直沒完的話就不斷的執(zhí)行,直到所有任務(wù)完成為止.至于任務(wù)完成后的從自己的待完成任務(wù)鏈表中刪除及添加到調(diào)度員的已完成任務(wù)鏈表中的工作由任務(wù)自己完成,工人無需管理,具體請看Task類的addCompleted方法.
run函數(shù)中,sleep的1000毫秒當(dāng)一個小時看,這里工人基本是當(dāng)24小時的班,即機(jī)器不閑著人三班倒,如果是日常的八小時任務(wù)則可以先取一下當(dāng)前時間是否在工作時間內(nèi),是則繼續(xù)干,如果不是應(yīng)該加入繼續(xù)休眠sleep的代碼.
工人類代碼如下:
package com.sitinspring.taskmanagement.domain;

import com.sitinspring.taskmanagement.util.IdUtil;


public class Worker implements Runnable
{
private String id;
private String name;
// 任務(wù)列表
private TaskBunch taskBunch;
// 工作速度
private int speed;

public Worker(String name,int speed)
{
id=IdUtil.generateId();
this.name=name;
this.speed=speed;
taskBunch=new TaskBunch();
}
// 添加任務(wù)

public void addTask(Task task)
{
task.setWorker(this);
taskBunch.addTask(task);
}
// 刪除任務(wù)

public void removeTask(Task task)
{
taskBunch.removeTask(task);
}
// 開始干活

public void doWork()
{
Thread thread=new Thread(this);
thread.start();
}
// 真正干活

public void run()
{

while(!taskBunch.isCompleted())
{

try
{
Thread.sleep(1000);
Task task=taskBunch.getTopTask();
task.addCompleted(speed);
System.out.println("正在處理的任務(wù)"+task+" 還需處理"+taskBunch.getSize()+"個.");
}

catch(Exception ex)
{
ex.printStackTrace();
}
}
System.out.println("工人"+name+"的全部任務(wù)處理完畢!");
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public String getId()
{
return id;
}
}
最后是調(diào)度員類,它的主要任務(wù)是生成任務(wù)以及管理已經(jīng)完成的任務(wù),代碼比較簡單:
package com.sitinspring.taskmanagement.domain;

import com.sitinspring.taskmanagement.util.IdUtil;


public class Attemper
{
private String id;
private String name;
private TaskBunch completedTasks;

public Attemper(String name)
{
id=IdUtil.generateId();
this.name=name;
completedTasks=new TaskBunch();
}

public Task generateTask(String name,int manHour,int priority)
{
Task task=new Task(name,manHour,priority);
task.setAttemper(this);
return task;
}

public void addCompletedTask(Task task)
{
completedTasks.addTask(task);
}


public String getId()
{
return id;
}


public String getName()
{
return name;
}
}
具體示例執(zhí)行過程如下:
Attemper Attemper=new Attemper("調(diào)度員");
Worker commonWorker=new Worker("普通工人一",2);
commonWorker.addTask(Attemper.generateTask("任務(wù)1",8,1));
commonWorker.addTask(Attemper.generateTask("任務(wù)2",9,2));
commonWorker.addTask(Attemper.generateTask("任務(wù)3",20,3));
commonWorker.doWork();
Worker skilledWorker=new Worker("熟練工人二",3);
skilledWorker.addTask(Attemper.generateTask("任務(wù)4",5,2));
skilledWorker.addTask(Attemper.generateTask("任務(wù)5",30,2));
skilledWorker.addTask(Attemper.generateTask("任務(wù)6",16,3));
skilledWorker.doWork();
Worker oldSkilledWorker=new Worker("老熟練工人三",5);
oldSkilledWorker.addTask(Attemper.generateTask("任務(wù)7",15,2));
oldSkilledWorker.addTask(Attemper.generateTask("任務(wù)8",13,2));
oldSkilledWorker.addTask(Attemper.generateTask("任務(wù)9",7,3));
oldSkilledWorker.doWork();
執(zhí)行輸出如下:
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:10% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)6 工人名:熟練工人二 完成度:18% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)9 工人名:老熟練工人三 完成度:71% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:20% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)6 工人名:熟練工人二 完成度:37% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)9 工人名:老熟練工人三 完成度:100% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:30% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)6 工人名:熟練工人二 完成度:56% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)7 工人名:老熟練工人三 完成度:33% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:40% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)6 工人名:熟練工人二 完成度:75% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)7 工人名:老熟練工人三 完成度:66% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:50% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)6 工人名:熟練工人二 完成度:93% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)7 工人名:老熟練工人三 完成度:100% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:60% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)6 工人名:熟練工人二 完成度:100% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)8 工人名:老熟練工人三 完成度:38% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:70% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)4 工人名:熟練工人二 完成度:60% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)8 工人名:老熟練工人三 完成度:76% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:80% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)4 工人名:熟練工人二 完成度:100% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)8 工人名:老熟練工人三 完成度:100% 還需處理0個.
工人老熟練工人三的全部任務(wù)處理完畢!
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:90% 還需處理3個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:10% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)3 工人名:普通工人一 完成度:100% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:20% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)2 工人名:普通工人一 完成度:22% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:30% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)2 工人名:普通工人一 完成度:44% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:40% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)2 工人名:普通工人一 完成度:66% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:50% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)2 工人名:普通工人一 完成度:88% 還需處理2個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:60% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)2 工人名:普通工人一 完成度:100% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:70% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)1 工人名:普通工人一 完成度:25% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:80% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)1 工人名:普通工人一 完成度:50% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:90% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)1 工人名:普通工人一 完成度:75% 還需處理1個.
正在處理的任務(wù)任務(wù)名:任務(wù)5 工人名:熟練工人二 完成度:100% 還需處理0個.
工人熟練工人二的全部任務(wù)處理完畢!
正在處理的任務(wù)任務(wù)名:任務(wù)1 工人名:普通工人一 完成度:100% 還需處理0個.
工人普通工人一的全部任務(wù)處理完畢!

代碼下載:
http://www.tkk7.com/Files/sitinspring/TaskManagement20071005131809.rar
以上.