工人自动获取任务的OO分析

工人自动获取任务的OO分析

这篇文章是" 调度员,工人及任务的OO分析过程"的续篇.

上次的情况是由调度员主动分配任务,但有些情况下需要工人自动取得任务而不是由调度员分配,这时需要对线程进行通知,使用的主要方法就是对象的wait(),notify(),notifyAll()三个函数,它们都必须从同步方法(synchronized method)中调用.

这种情况下事务的大致流程是:工人从任务库中取得一项任务进行作业,完成后再取下一项,如果任务库中没有任务则进入等待状态,如果任务库有新任务则通知工人来取.

这次新引入了一个任务库类TaskLibrary,它取代了上次的调度员类,代码如下:
package  com.sitinspring.autotask.domain;

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

/** */ /**
 * 任务库类
 * 
 * 
@author sitinspring([email protected])
 * 
 
*/

public   class  TaskLibrary  {
    
private List<Task> tasks;

    
public TaskLibrary() {
        tasks 
= new LinkedList<Task>();
    }


    
// 添加单个任务
    public synchronized void addTask(Task task) {
        tasks.add(task);
        notifyAll();
    }


    
// 添加多个任务
    public synchronized void addTasks(List<Task> moreTasks) {
        tasks.addAll(moreTasks);
        notifyAll();
    }


    
public int getTaskSize() {
        
return tasks.size();
    }


    
// 工人领受任务
    public synchronized Task fetchTask(Worker worker) {
        
while (tasks.size() == 0{
            
try {
                System.out.println(
"任务告罄");
                System.out.println(
"工人:" + worker.getName() + "进入闲置状态");
                wait();
            }
 catch (InterruptedException ex1) {
                ex1.printStackTrace();
            }

        }


        Task task 
= tasks.get(0);
        System.out.println(
"工人:" + worker.getName() + "取得任务:" + task.getName());
        tasks.remove(task);
        
return task;
    }

}

其中,fetchTask通过调用wait方法,实现了没有任务时则对自己(this)加锁(lock),以让进入的线程等待,否则让工人取走最开头的任务.
而addTask和addTasks通过调用notifyAll方法,通知等待的线程可以继续进行原来陷入等待状态的流程.

在这种情况下,工人类只需关心当前任务即可,它无须保存一个任务列表,具体代码如下:
package  com.sitinspring.autotask.domain;

import  com.sitinspring.autotask.util.IdUtil;

public   class  Worker  implements  Runnable  {
    
private String id;

    
private String name;

    
private Task currTask;

    
private TaskLibrary taskLibrary;

    
// 工作速度
    private int speed;

    
public Worker(String name, int speed, TaskLibrary taskLibrary) {
        id 
= IdUtil.generateId();
        
this.currTask = null;
        
this.name = name;
        
this.speed = speed;
        
this.taskLibrary = taskLibrary;

        doWork();
    }


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


    
// 真正干活
    public void run() {
        
while (true{
            
if (currTask == null || currTask.isCompleted()) {
                currTask 
= taskLibrary.fetchTask(this);
                currTask.setWorker(
this);
            }


            
try {
                Thread.sleep(
1000);
                System.out.println(
"正在处理的任务" + currTask + " 完成度"
                        
+ currTask.getCompletedRatio() + "个.");
                currTask.addCompleted(speed);
            }
 catch (Exception ex) {
                ex.printStackTrace();
            }

        }

    }


    
public String getName() {
        
return name;
    }


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


    
public String getId() {
        
return id;
    }

}
它的Run方法实现了不断取活干活的过程,因为具体进入等待是TaskLibrary做的,所以这个类代码很简单,这里就不赘述了.

执行过程如下:
package  com.sitinspring.autotask;

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

import  com.sitinspring.autotask.domain.Task;
import  com.sitinspring.autotask.domain.TaskLibrary;
import  com.sitinspring.autotask.domain.Worker;


public   class  Test {
    
public static void main(String[] args){
        TaskLibrary taskLibrary
=new TaskLibrary();        
        
        taskLibrary.addTask(
new Task("培训",8));
        
        List
<Task> moreTasks=new LinkedList<Task>();
        moreTasks.add(
new Task("锻造",4));
        moreTasks.add(
new Task("打磨",5));
        moreTasks.add(
new Task("车阶梯",6));
        moreTasks.add(
new Task("热处理",7));
        moreTasks.add(
new Task("去皮",8));
        moreTasks.add(
new Task("镗孔",60));
        moreTasks.add(
new Task("钻孔",10));
        moreTasks.add(
new Task("拉槽",11));
        
        taskLibrary.addTasks(moreTasks);    
        
        Worker worker01
=new Worker("王进喜",1,taskLibrary);
        Worker worker02
=new Worker("时传详",2,taskLibrary);
        Worker worker03
=new Worker("张秉贵",3,taskLibrary);
        Worker worker04
=new Worker("徐虎",3,taskLibrary);
        
        taskLibrary.addTask(
new Task("铸造",8));
        sleep(
1);
        taskLibrary.addTask(
new Task("校验",9));
        sleep(
2);
        taskLibrary.addTask(
new Task("内务",10));
        sleep(
3);
    }

    
    
private static void sleep(int sleepSecond){
        
try{
            Thread.sleep(sleepSecond
*1000);
        }

        
catch(Exception ex){
            ex.printStackTrace();
        }

    }

}


执行效果如下:
工人:王进喜取得任务:培训
工人:时传详取得任务:锻造
工人:张秉贵取得任务:打磨
工人:徐虎取得任务:车阶梯
正在处理的任务任务名:培训 工人名:王进喜 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:锻造 工人名:时传详 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:打磨 工人名:张秉贵 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:车阶梯 工人名:徐虎 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:培训 工人名:王进喜 完成度:
12 %  完成度 完成度: 12 % 个.
正在处理的任务任务名:锻造 工人名:时传详 完成度:
50 %  完成度 完成度: 50 % 个.
任务任务名:锻造 工人名:时传详 完成度:
100 % 处理完毕 !
工人:时传详取得任务:热处理
正在处理的任务任务名:打磨 工人名:张秉贵 完成度:
60 %  完成度 完成度: 60 % 个.
任务任务名:打磨 工人名:张秉贵 完成度:
100 % 处理完毕 !
正在处理的任务任务名:车阶梯 工人名:徐虎 完成度:
50 %  完成度 完成度: 50 % 个.
任务任务名:车阶梯 工人名:徐虎 完成度:
100 % 处理完毕 !
工人:徐虎取得任务:去皮
工人:张秉贵取得任务:镗孔
正在处理的任务任务名:培训 工人名:王进喜 完成度:
25 %  完成度 完成度: 25 % 个.
正在处理的任务任务名:热处理 工人名:时传详 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:去皮 工人名:徐虎 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:培训 工人名:王进喜 完成度:
37 %  完成度 完成度: 37 % 个.
正在处理的任务任务名:热处理 工人名:时传详 完成度:
28 %  完成度 完成度: 28 % 个.
正在处理的任务任务名:去皮 工人名:徐虎 完成度:
37 %  完成度 完成度: 37 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
5 %  完成度 完成度: 5 % 个.
正在处理的任务任务名:培训 工人名:王进喜 完成度:
50 %  完成度 完成度: 50 % 个.
正在处理的任务任务名:热处理 工人名:时传详 完成度:
57 %  完成度 完成度: 57 % 个.
正在处理的任务任务名:去皮 工人名:徐虎 完成度:
75 %  完成度 完成度: 75 % 个.
任务任务名:去皮 工人名:徐虎 完成度:
100 % 处理完毕 !
工人:徐虎取得任务:钻孔
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
10 %  完成度 完成度: 10 % 个.
正在处理的任务任务名:培训 工人名:王进喜 完成度:
62 %  完成度 完成度: 62 % 个.
正在处理的任务任务名:热处理 工人名:时传详 完成度:
85 %  完成度 完成度: 85 % 个.
任务任务名:热处理 工人名:时传详 完成度:
100 % 处理完毕 !
工人:时传详取得任务:拉槽
正在处理的任务任务名:钻孔 工人名:徐虎 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
15 %  完成度 完成度: 15 % 个.
正在处理的任务任务名:培训 工人名:王进喜 完成度:
75 %  完成度 完成度: 75 % 个.
正在处理的任务任务名:拉槽 工人名:时传详 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:钻孔 工人名:徐虎 完成度:
30 %  完成度 完成度: 30 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
20 %  完成度 完成度: 20 % 个.
正在处理的任务任务名:培训 工人名:王进喜 完成度:
87 %  完成度 完成度: 87 % 个.
任务任务名:培训 工人名:王进喜 完成度:
100 % 处理完毕 !
工人:王进喜取得任务:铸造
正在处理的任务任务名:拉槽 工人名:时传详 完成度:
18 %  完成度 完成度: 18 % 个.
正在处理的任务任务名:钻孔 工人名:徐虎 完成度:
60 %  完成度 完成度: 60 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
25 %  完成度 完成度: 25 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:拉槽 工人名:时传详 完成度:
36 %  完成度 完成度: 36 % 个.
正在处理的任务任务名:钻孔 工人名:徐虎 完成度:
90 %  完成度 完成度: 90 % 个.
任务任务名:钻孔 工人名:徐虎 完成度:
100 % 处理完毕 !
工人:徐虎取得任务:校验
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
30 %  完成度 完成度: 30 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
12 %  完成度 完成度: 12 % 个.
正在处理的任务任务名:拉槽 工人名:时传详 完成度:
54 %  完成度 完成度: 54 % 个.
正在处理的任务任务名:校验 工人名:徐虎 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
35 %  完成度 完成度: 35 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
25 %  完成度 完成度: 25 % 个.
正在处理的任务任务名:拉槽 工人名:时传详 完成度:
72 %  完成度 完成度: 72 % 个.
正在处理的任务任务名:校验 工人名:徐虎 完成度:
33 %  完成度 完成度: 33 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
40 %  完成度 完成度: 40 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
37 %  完成度 完成度: 37 % 个.
正在处理的任务任务名:拉槽 工人名:时传详 完成度:
90 %  完成度 完成度: 90 % 个.
任务任务名:拉槽 工人名:时传详 完成度:
100 % 处理完毕 !
工人:时传详取得任务:内务
正在处理的任务任务名:校验 工人名:徐虎 完成度:
66 %  完成度 完成度: 66 % 个.
任务任务名:校验 工人名:徐虎 完成度:
100 % 处理完毕 !
任务告罄
工人:徐虎进入闲置状态
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
45 %  完成度 完成度: 45 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
50 %  完成度 完成度: 50 % 个.
正在处理的任务任务名:内务 工人名:时传详 完成度:
0 %  完成度 完成度: 0 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
50 %  完成度 完成度: 50 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
62 %  完成度 完成度: 62 % 个.
正在处理的任务任务名:内务 工人名:时传详 完成度:
20 %  完成度 完成度: 20 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
55 %  完成度 完成度: 55 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
75 %  完成度 完成度: 75 % 个.
正在处理的任务任务名:内务 工人名:时传详 完成度:
40 %  完成度 完成度: 40 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
60 %  完成度 完成度: 60 % 个.
正在处理的任务任务名:铸造 工人名:王进喜 完成度:
87 %  完成度 完成度: 87 % 个.
任务任务名:铸造 工人名:王进喜 完成度:
100 % 处理完毕 !
任务告罄
工人:王进喜进入闲置状态
正在处理的任务任务名:内务 工人名:时传详 完成度:
60 %  完成度 完成度: 60 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
65 %  完成度 完成度: 65 % 个.
正在处理的任务任务名:内务 工人名:时传详 完成度:
80 %  完成度 完成度: 80 % 个.
任务任务名:内务 工人名:时传详 完成度:
100 % 处理完毕 !
任务告罄
工人:时传详进入闲置状态
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
70 %  完成度 完成度: 70 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
75 %  完成度 完成度: 75 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
80 %  完成度 完成度: 80 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
85 %  完成度 完成度: 85 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
90 %  完成度 完成度: 90 % 个.
正在处理的任务任务名:镗孔 工人名:张秉贵 完成度:
95 %  完成度 完成度: 95 % 个.
任务任务名:镗孔 工人名:张秉贵 完成度:
100 % 处理完毕 !
任务告罄
工人:张秉贵进入闲置状态

代码下载:
http://www.blogjava.net/Files/sitinspring/AutoTask20071020100536.rar


你可能感兴趣的:(工人自动获取任务的OO分析)