java 板


LINE

这不是流程的问题 是资料结构的问题 如果是自己写程式的话 那就用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







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:e-shopping站内搜寻

TOP