robin_77
偷懒是一种必备素质

本文属原创,转载请注明出处:http://www.cnblogs.com/robinjava77/p/5455207.html (Robin)

业务场景是这样的:
1.定义了一个抽象类:抽象类有有两个方法main()和business();
2.main()是具体方法,规范了业务流程;business()是抽象方法,由各个子类实现具体的业务逻辑;
3.main()里面有一不调用business(),由于business()比较费时,而且main需要多次调用business,所以main要能异步调用business()

4.main异步调用business()后,继续其他工作,完成其他工作后,等待所有business完成各自的流程,返回结果给main,然后main再统一继续剩余流程

 

具体办法,还在思考...

2016.05.03

---------------------------------------------------

新解决方案

1.使用java.util.concurrent.CompletionService 来对异步执行的任务进行添加和获取反馈结果;

 1 import java.util.concurrent.*;
 2 
 3 /**
 4  * Created by robin on 2016/5/4.
 5  *
 6  * @author robin
 7  */
 8 public class MyFutureTaskTest {
 9 
10     public static void main(String[] args) throws Exception {
11         int n = 4;
12         ExecutorService threadPool = Executors.newCachedThreadPool();
13         CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);
14         for(int i=0;i<n;i++){
15             final int temp = i;
16             cs.submit(new Callable<Integer>() {
17                 public Integer call() throws Exception {
18                     int i = business(temp);
19                     return i;
20                 }
21             });
22             System.out.println("main在继续进行流程规范,循环次数:" + (i+1));
23         }
24         System.out.println("循环已结束,main在执行其他流程规范。");
25         System.out.println("main执行完其他流程规范,现在开始等待异步调用的business()群执行完毕,才能继续");
26         int result = 0;
27         for(int i=0;i<n;i++){
28             result += cs.take().get();//自动获取当前池中最先完成的任务反馈结果,若此时没有,则阻塞
29         }
30         System.out.print("business已异步跑完,计算结果:"+result);
31     }
32 
33     public static Integer business(int i) throws InterruptedException {
34         System.out.println("开始执行business方法,标志号:" + i);
35         Thread.sleep(5000);//
36         System.out.println("business执行完毕,标志号:"+i);
37         return i;
38     }
39 }

执行结果

main在继续进行流程规范,循环次数:1
main在继续进行流程规范,循环次数:2
main在继续进行流程规范,循环次数:3
main在继续进行流程规范,循环次数:4
循环已结束,main在执行其他流程规范。
main执行完其他流程规范,现在开始等待异步调用的business()群执行完毕,才能继续
开始执行business方法,标志号:0
开始执行business方法,标志号:1
开始执行business方法,标志号:3
开始执行business方法,标志号:2
business执行完毕,标志号:0
business执行完毕,标志号:1
business执行完毕,标志号:3
business执行完毕,标志号:2
business已异步跑完,计算结果:6
Process finished with exit code 0

2016.05.04

---------------------------------------------------

旧解决方案(已使用新解决方案):

1.使用java.util.concurrent.Future类,来异步执行business(),并且返回执行后的结果;

2.使用java.util.concurrent.CountDownLatch类,来对异步执行的Future群,进行同步管理;

具体代码:

 1 package concurrentTest;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 import java.util.concurrent.*;
 6 
 7 /**
 8  * Created by robin on 2016/5/3.
 9  *
10  * @author robin
11  */
12 public class MyFutureTaskTest {
13 
14     public static void main(String[] args) throws Exception {
15         int n = 4;
16         final CountDownLatch doneFlag = new CountDownLatch(n);//结束倒数锁
17         Map<String,Future<Integer>> threadMap = new HashMap<String,Future<Integer>>();//异步线程执行返回结果容器
18         Future<Integer> future = null;
19         for(int i=0;i<n;i++){
20             final int temp = i;
21             ExecutorService threadPool = Executors.newCachedThreadPool();
22             future = threadPool.submit(new Callable<Integer>() {
23                 public Integer call() throws Exception {
24                     int i = business(temp);
25                     doneFlag.countDown();//通知结束倒数锁本线程完成计算
26                     return i;
27                 }
28             });
29             threadMap.put("" + i, future);
30             System.out.println("main在继续进行流程规范,循环次数:" + (i+1));
31         }
32         System.out.println("循环已结束,main在执行其他流程规范。");
33         System.out.println("main执行完其他流程规范,现在开始等待异步调用的business()群执行完毕,才能继续");
34         doneFlag.await();//父线程等待所有子线程完成计算
35         int result = 0;
36         for (Map.Entry<String,Future<Integer>> entry:threadMap.entrySet()){
37             result += entry.getValue().get();//获取每个business执行后的结果
38         }
39         System.out.print("business已异步跑完,计算结果:"+result);
40 
41     }
42 
43     public static Integer business(int i) throws InterruptedException {
44         System.out.println("开始执行business方法,标志号:" + i);
45         Thread.sleep(5000);//
46         System.out.println("business执行完毕,标志号:"+i);
47         return i;
48     }
49 
50 }

执行结果

main在继续进行流程规范,循环次数:1
main在继续进行流程规范,循环次数:2
main在继续进行流程规范,循环次数:3
main在继续进行流程规范,循环次数:4
循环已结束,main在执行其他流程规范。
main执行完其他流程规范,现在开始等待异步调用的business()群执行完毕,才能继续
开始执行business方法,标志号:1
开始执行business方法,标志号:3
开始执行business方法,标志号:2
开始执行business方法,标志号:0
business执行完毕,标志号:1
business执行完毕,标志号:2
business执行完毕,标志号:3
business执行完毕,标志号:0
business已异步跑完,计算结果:6
Process finished with exit code 0

2016.05.03

 

posted on 2016-05-03 15:41  robin_77  阅读(381)  评论(0编辑  收藏  举报