作者swpoker (swpoker)
标题Re: [问题] 请问有办法设定编号来决定排程吗
时间Mon Nov 17 11:53:31 2014
这不是流程的问题
是资料结构的问题
如果是自己写程式的话
那就用popcorny的CompletableFuture来写程式安排,比较有弹性
但是你想要用资料库来驱动的话
那就会变成是tree结构了
因此要用爬节点的方式才能符合你的需求
所以我用爬节点的方式,还是使用ForkJoinPool来实作
就可以透过节点的关系来驱动实际的行为
---
其实爬节点可以用RecursiveTask实作,但有谁可以教学一下吗?
我对於fork join还是不太会用
---
package com.swpoker;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
/**
*/
public class Test5 {
static class ExecuteBean{
public String name;
public String memo;
public int waittime;
public ExecuteBean(String name, String memo, int waittime ){
this.name=name;
this.memo=memo;
this.waittime=waittime;
}
}
static List<ExecuteBean> simulateExecute(){
List<ExecuteBean> rs = new ArrayList();
rs.add(new ExecuteBean("A","A1",1));
rs.add(new ExecuteBean("B","B1",12));
rs.add(new ExecuteBean("C","C1",2));
rs.add(new ExecuteBean("D","D1",4));
rs.add(new ExecuteBean("E","E1",5));
rs.add(new ExecuteBean("F","F1",2));
rs.add(new ExecuteBean("H","H1",10));
return rs;
}
static class DependBean{
public String name;
public String depend;
public DependBean(String name, String depend){
this.name=name;
this. depend=depend;
}
}
static List<DependBean> simulatDepend(){
List<DependBean> rs = new ArrayList();
rs.add(new DependBean("A",""));
rs.add(new DependBean("B","A"));
rs.add(new DependBean("C","A"));
rs.add(new DependBean("D","C"));
rs.add(new DependBean("E","B"));
rs.add(new DependBean("E","D"));
rs.add(new DependBean("F","C"));
rs.add(new DependBean("H","B"));
rs.add(new DependBean("H","C"));
return rs;
}
static List<ExecuteBean> findChildNode(String name , List<DependBean>
dependlist,List<ExecuteBean> executelist){
List<ExecuteBean> rs = new ArrayList();
dependlist.stream().filter( db -> db.depend.equals(name) ).forEach(db
-> rs.add(
executelist.stream().filter(e ->
e.name.equals(db.name)).findFirst().get()
));
return rs;
}
static class ExecuteActor {
ExecuteBean bean;
public ExecuteActor(ExecuteBean bean){
this.bean=bean;
}
public void dosomething(){
try{
long waittime =bean.waittime * 1000;
System.out.printf("%s start wait(%s)
%s\n",this.bean.memo,waittime, Calendar.getInstance().getTime());
//do something
Thread.sleep(waittime);
System.out.printf("%s end %s\n",this.bean.memo,
Calendar.getInstance().getTime());
}catch (Exception e){e.printStackTrace();}
}
}
private static Map<String, List<String>>
buildInVokeDepends(List<ExecuteBean> executelist, List<DependBean>
dependlist) {
Map<String, List<String>> dependrs = new HashMap();
executelist.stream().forEach( eb -> {
dependrs.put(eb.name,new ArrayList());
dependlist.stream().filter( de -> eb.name.equals(de.name) &&
Optional.ofNullable(de.depend).orElse("").isEmpty() == false ).forEach(
de -> dependrs.get(eb.name).add(de.depend)
);
} );
return dependrs;
}
private static ExecuteBean findFistExecute(List<DependBean> dependlist,
List<ExecuteBean> executelist) {
DependBean fisrtdb = dependlist.stream().filter(d
->Optional.ofNullable(d.depend).orElse("").isEmpty()).findFirst().get();
return
executelist.stream().filter(eb->eb.name.equals(fisrtdb.name)).findFirst().get();
}
static boolean invokeAndCheckExecuteBean(ExecuteBean
parentbean,ExecuteBean bean,Map<String,List<String>> invokedenpends){
if(parentbean == null){
return true;
}
synchronized (invokedenpends){
List<String> invokedenpend=invokedenpends.get(bean.name);
invokedenpend.remove(parentbean.name);
return invokedenpend.isEmpty();
}
}
static class NodeExecuteActor implements Runnable{
ExecuteBean parentbean ;
ExecuteBean bean;
ForkJoinPool forkJoinPool;
List<DependBean> dependlist;
List<ExecuteBean> executelist ;
Map<String, List<String>> inVokeDepends;
public NodeExecuteActor(ExecuteBean parentbean ,ExecuteBean
bean,ForkJoinPool forkJoinPool, List<DependBean> dependlist,List<ExecuteBean>
executelist,Map<String, List<String>> inVokeDepends){
this.parentbean=parentbean;
this.bean=bean;
this.forkJoinPool=forkJoinPool;
this.dependlist=dependlist;
this.executelist=executelist;
this.inVokeDepends=inVokeDepends;
}
@Override
public void run() {
System.out.printf("NodeExecuteActor %s start
%s\n",this.bean.name, Calendar.getInstance().getTime());
//check
if(invokeAndCheckExecuteBean(this.parentbean,this.bean,
this.inVokeDepends) == false){
return;
}
//excute self
new ExecuteActor( this.bean).dosomething();
//then invoke child
invokeChild(this.bean,this.forkJoinPool,
this.dependlist,this.executelist,this.inVokeDepends);
}
}
static void dealNode(ExecuteBean parentbean , ExecuteBean bean
,ForkJoinPool forkJoinPool, List<DependBean> dependlist,List<ExecuteBean>
executelist,Map<String, List<String>> inVokeDepends){
forkJoinPool.execute(new
NodeExecuteActor(parentbean,bean,forkJoinPool,dependlist,executelist,inVokeDepends));
}
static void invokeChild(ExecuteBean bean,ForkJoinPool forkJoinPool,
List<DependBean> dependlist,List<ExecuteBean> executelist,Map<String,
List<String>> inVokeDepends){
for(ExecuteBean eb : findChildNode(
bean.name,dependlist,executelist)){
dealNode(bean,eb,forkJoinPool,dependlist,executelist,
inVokeDepends);
}
}
static void startFirstNode(ExecuteBean bean ,ForkJoinPool forkJoinPool,
List<DependBean> dependlist,List<ExecuteBean> executelist,Map<String,
List<String>> inVokeDepends){
// invokeChild(bean,forkJoinPool,
dependlist,executelist,inVokeDepends);
dealNode(null, bean , forkJoinPool, dependlist,executelist,
inVokeDepends);
}
public static void main(String [] args) throws Exception{
System.out.printf("main start %s\n",
Calendar.getInstance().getTime());
List<ExecuteBean> executelist = simulateExecute();
List<DependBean> dependlist=simulatDepend();
Map<String,List<String>>
invokedepends=buildInVokeDepends(executelist, dependlist);
ExecuteBean firstBean = findFistExecute(dependlist,executelist);
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
//start
startFirstNode(firstBean,forkJoinPool,dependlist,executelist,invokedepends);
forkJoinPool.shutdown();
forkJoinPool.awaitTermination(1, TimeUnit.DAYS);
System.out.printf("main end %s\n", Calendar.getInstance().getTime());
}
}
※ 引述《PTTCATKING (怀念美国猫王)》之铭言:
: 现在一个流程是这样
: Thread A 执行完成之後,分成两条Thread,同时执行 B跟 C
: 然後C这条线执行完後,会再执行D
: 等到B这条线跟 C&D这条线两条都跑完後,才开始执行E
: 如果像是我以下这种写法,算是 B跟 CD跑完之後,才开始跑E吗
: 那一开始起头的 A 我要怎麽写呢
: public void execute(TaskExecutionContext executor) throws RuntimeException {
: System.out.println("Thread E ");
: Thread threadB = new Thread(new Runnable() {
: public void run() {
: try {
: System.out.println("Thread B 开始..");
: for(int i = 0; i < 5; i++) {
: Thread.sleep(1000);
: System.out.println("Thread B 执行..");
: }
: System.out.println("Thread B 即将结束..");
: }
: catch(InterruptedException e) {
: e.printStackTrace();
: }
: }
: });
: Thread threadC = new Thread(new Runnable() {
: public void run() {
: try {
: System.out.println("Thread C 开始..");
: for(int i = 0; i < 5; i++) {
: Thread.sleep(1000);
: System.out.println("Thread C 执行..");
: }
: System.out.println("Thread C 即将结束..");
: System.out.println("Thread D 开始..");
: for(int i = 0; i < 5; i++) {
: Thread.sleep(1000);
: System.out.println("Thread D 执行..");
: }
: System.out.println("Thread D 即将结束..");
: }
: catch(InterruptedException e) {
: e.printStackTrace();
: }
: }
: });
: threadB.start();
: threadC.start();
: try {
: // Thread B 加入 Thread A
: threadB.join();
: threadC.join();
: }
: catch(InterruptedException e) {
: e.printStackTrace();
: }
: System.out.println("Thread E 执行");
: for (int i = 1; i <= 30; i++) {
: System.out.println("Task 1 says: " + i + executor);
: executor.setStatusMessage("第一个任务执行到第 " + i + " 个");
: executor.setCompleteness(i / 30D);
: try {
: Thread.sleep(1000);
: } catch (InterruptedException e) {
: ;
: }
: executor.pauseIfRequested();
: if (executor.isStopped()) {
: break;
: }
: }
: }
: 格式可能有点跑掉,这是 让E等待 B跟CD的写法
: 怎麽写成从A开始呢
: 因为 E 就是主程序了说..
※ 引述《PTTCATKING (怀念美国猫王)》之铭言:
: 假设有二十个任务要跑
: 而他在DB里会有两组编号(栏位名称)
: 第一组是1~20的流水号
: 第二组是执行优先顺序(记录需等待的对象)
: A 跑完 同时执行 B & CD 两条线同时跑,而B会先跑完,但要等CD都跑完後,BCD都结束
: 才开始跑E
: A的编号就是 1 0 (无等待对象)
: B的编号就是 2 1 (等待A,1是A的编号)
: C的编号就是 3 1 (等待A,1是A的编号)
: D的编号就是 4 3 (等待C,3是C的编号)
: E的编号就是 5 2 (等待B,2是B的编号)
: E的编号就是 5 4 (等待D,4是D的编号)
: 因为E要等两个,所以在DB里 E 会有两笔资料
: 请问 有没有什麽现有套件有能够执行这件事情呢
: 设定那两个编号,则程式执行後就按照两个编号,决定程式优先顺序,并有可能同时执行
: 多程序
: 以後维护就是设定编号就能决定跑程式的优先顺序
: 今天用CountDownLatch写出类似的东西,被认为是写死的东西orz
: 这是用排程器???或是什麽方向呢?? @O@
: 能否有高手指点明灯给我方向,谢谢 T_T
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 163.29.29.131
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/java/M.1416196414.A.4B7.html
※ 编辑: swpoker (163.29.29.131), 11/17/2014 13:41:10
1F:→ popcorny: Task Dependency是DAG.. 可以直接找DAG的Library.. 11/17 15:07
2F:→ swpoker: 哈~当作作业练习练习 XD 11/18 09:22