春风博客

春天里,百花香...

导航

<2007年10月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

统计

公告

MAIL: junglesong@gmail.com
MSN: junglesong_5@hotmail.com

Locations of visitors to this page

常用链接

留言簿(11)

随笔分类(224)

随笔档案(126)

个人软件下载

我的其它博客

我的邻居们

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

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

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

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

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

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

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

/**
 * 任务库类
 * 
 * 
@author sitinspring(junglesong@gmail.com)
 * 
 
*/

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


posted on 2007-10-20 09:53 sitinspring 阅读(863) 评论(0)  编辑  收藏 所属分类: Object Orient Programming


只有注册用户登录后才能发表评论。


网站导航:
 
sitinspring(http://www.blogjava.net)原创,转载请注明出处.