模板模式實現任務分配
阿新 • • 發佈:2018-12-26
場景:有m臺伺服器,有n個任務,需要把n個任務按一定策略分給伺服器來執行。如按IP地址隨機分、按任務數量平均分等。
實現約定:使用一個list來代表全部伺服器,比如list中只存伺服器的IP地址。同樣使用list來代表任務,比如list中存每個任務的ID。分配的過程也就是把伺服器IP和任務ID對映起來的過程,所以可以用一個Map 來儲存分本結果。
實現:
先建立一個模板類 TaskWorker
import java.util.*; public abstract class TaskWorker { public List<String> serviceList ; public List<Long> taskList ; public Map<Long , String > taskMap ; public TaskWorker(){ } public TaskWorker(List<String> serviceList ,List<Long> taskList){ this.serviceList = serviceList ; this.taskList = taskList ; this.taskMap = new HashMap<>() ; } public TaskWorker buildService(List<String> serviceList){ if(this.serviceList == null){ this.serviceList = new ArrayList<>() ; this.serviceList.addAll(serviceList); }else{ this.serviceList.addAll(serviceList); } return this ; } public TaskWorker buildTask(List<Long> taskList){ if(this.taskList == null){ this.taskList = new ArrayList<>() ; this.taskList.addAll(taskList); }else{ this.taskList.addAll(taskList); } return this ; } /** * 分配任務 */ abstract void allocation(); /** * 任務執行簡化為迭代MAP 列印中其中的k - v * 分析其中的任務ID及伺服器ID 來看分配策略是否正確 */ public void excute(){ if(this.taskMap == null){ System.out.println("無任務!"); } else{ Set<Long > set = this.taskMap.keySet(); for(Long key : set ){ System.out.println("任務ID為:"+key+"--->執行它的伺服器為:"+taskMap.get(key)); } } } /** * 總排程方法 */ public final void processed(){ allocation() ; excute() ; } }
隨機分配 RandomTaskWorker
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.HashMap; import java.util.Random; public class RandomTaskWorker extends TaskWorker { Log log = LogFactory.getLog(RandomTaskWorker.class); /** * 按IP地址隨機 */ @Override void allocation() { if(this.serviceList == null || this.taskList == null || serviceList.size()<0 || taskList.size() <0){ log.error("service or task do not exist"); return ; } if(this.taskMap==null) { this.taskMap = new HashMap<>(); } for(int i=0 ; i<this.taskList.size() ; i++){ Random rnd = new Random(); taskMap.put(this.taskList.get(i) ,serviceList.get(rnd.nextInt(serviceList.size()))); } } }
平均分配
import java.util.HashMap; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class AverageTaskWorker extends TaskWorker { Log log = LogFactory.getLog(AverageTaskWorker.class); /** * 分配任務方式為按任務數量平均分 * 1.當任務數量比伺服器數量少時,一臺伺服器分一個任務; * 2.當任務資料比伺服器數量多時,平分的 */ @Override void allocation() { if(this.serviceList == null || this.taskList == null || serviceList.size()<0 || taskList.size() <0){ log.error("service or task do not exist"); return ; } if(this.taskMap==null) { this.taskMap = new HashMap<>(); } if(serviceList.size() >= taskList.size()){ int cur = 0; for(Long taskKey :taskList){ taskMap.put(taskKey ,serviceList.get(cur)); cur ++ ; } } else{ for(Long taskKey : taskList){ int left = taskKey.intValue() % serviceList.size() ; taskMap.put(taskKey ,serviceList.get(left)); } } } }
測試方法
import java.util.ArrayList;
import java.util.List;
public class TaskWorkerTest {
public static void main(String[] args){
TaskWorker tk = new AverageTaskWorker();
TaskWorker rtk = new RandomTaskWorker();
List<Long> taskList = getTask(31);
List<String> serviceList = getService(15 ) ;
tk.buildTask(taskList).buildService(serviceList) ;
tk.processed();
System.out.println("<---------我是華麗的分割線------------->");
rtk.buildTask(taskList).buildService(serviceList) ;
rtk.processed();
}
public static List<Long> getTask(int taskSize){
if(taskSize <1){
return null ;
}
List<Long> taskList = new ArrayList<>();
for(int i=0 ; i <taskSize ;i++ ){
taskList.add(new Long(i)) ;
}
return taskList ;
}
public static List<String> getService(int ServiceSize){
if(ServiceSize <1){
return null ;
}
List<String> serviceList = new ArrayList<>();
for(int i=0 ; i <ServiceSize ;i++ ){
serviceList.add("伺服器00"+ i) ;
}
return serviceList ;
}
}
測試結果
任務ID為:0--->執行它的伺服器為:伺服器000
任務ID為:1--->執行它的伺服器為:伺服器001
任務ID為:2--->執行它的伺服器為:伺服器002
任務ID為:3--->執行它的伺服器為:伺服器003
任務ID為:4--->執行它的伺服器為:伺服器004
任務ID為:5--->執行它的伺服器為:伺服器005
任務ID為:6--->執行它的伺服器為:伺服器006
任務ID為:7--->執行它的伺服器為:伺服器007
任務ID為:8--->執行它的伺服器為:伺服器008
任務ID為:9--->執行它的伺服器為:伺服器009
任務ID為:10--->執行它的伺服器為:伺服器0010
任務ID為:11--->執行它的伺服器為:伺服器0011
任務ID為:12--->執行它的伺服器為:伺服器0012
任務ID為:13--->執行它的伺服器為:伺服器0013
任務ID為:14--->執行它的伺服器為:伺服器0014
任務ID為:15--->執行它的伺服器為:伺服器000
任務ID為:16--->執行它的伺服器為:伺服器001
任務ID為:17--->執行它的伺服器為:伺服器002
任務ID為:18--->執行它的伺服器為:伺服器003
任務ID為:19--->執行它的伺服器為:伺服器004
任務ID為:20--->執行它的伺服器為:伺服器005
任務ID為:21--->執行它的伺服器為:伺服器006
任務ID為:22--->執行它的伺服器為:伺服器007
任務ID為:23--->執行它的伺服器為:伺服器008
任務ID為:24--->執行它的伺服器為:伺服器009
任務ID為:25--->執行它的伺服器為:伺服器0010
任務ID為:26--->執行它的伺服器為:伺服器0011
任務ID為:27--->執行它的伺服器為:伺服器0012
任務ID為:28--->執行它的伺服器為:伺服器0013
任務ID為:29--->執行它的伺服器為:伺服器0014
任務ID為:30--->執行它的伺服器為:伺服器000
<---------我是華麗的分割線------------->
任務ID為:0--->執行它的伺服器為:伺服器001
任務ID為:1--->執行它的伺服器為:伺服器0014
任務ID為:2--->執行它的伺服器為:伺服器003
任務ID為:3--->執行它的伺服器為:伺服器006
任務ID為:4--->執行它的伺服器為:伺服器0014
任務ID為:5--->執行它的伺服器為:伺服器007
任務ID為:6--->執行它的伺服器為:伺服器0010
任務ID為:7--->執行它的伺服器為:伺服器007
任務ID為:8--->執行它的伺服器為:伺服器006
任務ID為:9--->執行它的伺服器為:伺服器009
任務ID為:10--->執行它的伺服器為:伺服器000
任務ID為:11--->執行它的伺服器為:伺服器003
任務ID為:12--->執行它的伺服器為:伺服器005
任務ID為:13--->執行它的伺服器為:伺服器001
任務ID為:14--->執行它的伺服器為:伺服器004
任務ID為:15--->執行它的伺服器為:伺服器004
任務ID為:16--->執行它的伺服器為:伺服器005
任務ID為:17--->執行它的伺服器為:伺服器0011
任務ID為:18--->執行它的伺服器為:伺服器0014
任務ID為:19--->執行它的伺服器為:伺服器0011
任務ID為:20--->執行它的伺服器為:伺服器0011
任務ID為:21--->執行它的伺服器為:伺服器0014
任務ID為:22--->執行它的伺服器為:伺服器007
任務ID為:23--->執行它的伺服器為:伺服器007
任務ID為:24--->執行它的伺服器為:伺服器0013
任務ID為:25--->執行它的伺服器為:伺服器0013
任務ID為:26--->執行它的伺服器為:伺服器007
任務ID為:27--->執行它的伺服器為:伺服器0012
任務ID為:28--->執行它的伺服器為:伺服器001
任務ID為:29--->執行它的伺服器為:伺服器008
任務ID為:30--->執行它的伺服器為:伺服器0013