春風博客

          春天里,百花香...

          導航

          <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.aygfsteel.com/Files/sitinspring/AutoTask20071020100536.rar


          posted on 2007-10-20 09:53 sitinspring 閱讀(880) 評論(0)  編輯  收藏 所屬分類: Object Orient Programming

          sitinspring(http://www.aygfsteel.com)原創,轉載請注明出處.
          主站蜘蛛池模板: 湘潭市| 南华县| 玛多县| 普格县| 昭苏县| 冕宁县| 牡丹江市| 抚州市| 甘孜| 仪征市| 马关县| 廉江市| 灵武市| SHOW| 磴口县| 班戈县| 尼玛县| 奎屯市| 南汇区| 肇源县| 邹平县| 安义县| 焦作市| 南昌市| 清河县| 贡嘎县| 新蔡县| 蛟河市| 吉木萨尔县| 分宜县| 枣强县| 南澳县| 吉林省| 西畴县| 山东| 东至县| 麻栗坡县| 唐河县| 兴仁县| 徐水县| 盱眙县|