dependWrappers;
+ /**
+ * 标记该事件是否已经被处理过了,譬如已经超时返回false了,后续rpc又收到返回值了,则不再二次回调
+ * 经试验,volatile并不能保证"同一毫秒"内,多线程对该值的修改和拉取
+ *
+ * 1-finish, 2-error, 3-working
+ */
+ private AtomicInteger state = new AtomicInteger(0);
+ /**
+ * 该map存放所有wrapper的id和wrapper映射
+ */
+ private Map forParamUseWrappers;
+ /**
+ * 也是个钩子变量,用来存临时的结果
+ */
+ private volatile WorkResult workResult = WorkResult.defaultResult();
+ /**
+ * 是否在执行自己前,去校验nextWrapper的执行结果
+ * 1 4
+ * -------3
+ * 2
+ * 如这种在4执行前,可能3已经执行完毕了(被2执行完后触发的),那么4就没必要执行了。
+ * 注意,该属性仅在nextWrapper数量<=1时有效,>1时的情况是不存在的
+ */
+ private volatile boolean needCheckNextWrapperResult = true;
+
+ private static final int FINISH = 1;
+ private static final int ERROR = 2;
+ private static final int WORKING = 3;
+ private static final int INIT = 0;
+
+ private WorkerWrapper(String id, IWorker worker, T param, ICallback callback) {
+ if (worker == null) {
+ throw new NullPointerException("async.worker is null");
+ }
+ this.worker = worker;
+ this.param = param;
+ this.id = id;
+ //允许不设置回调
+ if (callback == null) {
+ callback = new DefaultCallback<>();
+ }
+ this.callback = callback;
+ }
+
+ /**
+ * 开始工作
+ * fromWrapper代表这次work是由哪个上游wrapper发起的
+ */
+ private void work(ThreadPoolExecutor poolExecutor, WorkerWrapper fromWrapper, long remainTime, Map forParamUseWrappers) {
+ this.forParamUseWrappers = forParamUseWrappers;
+ //将自己放到所有wrapper的集合里去
+ forParamUseWrappers.put(id, this);
+ long now = SystemClock.now();
+ //总的已经超时了,就快速失败,进行下一个
+ if (remainTime <= 0) {
+ fastFail(INIT, null);
+ beginNext(poolExecutor, now, remainTime);
+ return;
+ }
+ //如果自己已经执行过了。
+ //可能有多个依赖,其中的一个依赖已经执行完了,并且自己也已开始执行或执行完毕。当另一个依赖执行完毕,又进来该方法时,就不重复处理了
+ if (getState() == FINISH || getState() == ERROR) {
+ beginNext(poolExecutor, now, remainTime);
+ return;
+ }
+
+ //如果在执行前需要校验nextWrapper的状态
+ if (needCheckNextWrapperResult) {
+ //如果自己的next链上有已经出结果或已经开始执行的任务了,自己就不用继续了
+ if (!checkNextWrapperResult()) {
+ fastFail(INIT, new SkippedException());
+ beginNext(poolExecutor, now, remainTime);
+ return;
+ }
+ }
+
+ //如果没有任何依赖,说明自己就是第一批要执行的
+ if (dependWrappers == null || dependWrappers.size() == 0) {
+ fire();
+ beginNext(poolExecutor, now, remainTime);
+ return;
+ }
+
+ /*如果有前方依赖,存在两种情况
+ 一种是前面只有一个wrapper。即 A -> B
+ 一种是前面有多个wrapper。A C D -> B。需要A、C、D都完成了才能轮到B。但是无论是A执行完,还是C执行完,都会去唤醒B。
+ 所以需要B来做判断,必须A、C、D都完成,自己才能执行 */
+
+ //只有一个依赖
+ if (dependWrappers.size() == 1) {
+ doDependsOneJob(fromWrapper);
+ beginNext(poolExecutor, now, remainTime);
+ } else {
+ //有多个依赖时
+ doDependsJobs(poolExecutor, dependWrappers, fromWrapper, now, remainTime);
+ }
+
+ }
+
+
+ public void work(ThreadPoolExecutor poolExecutor, long remainTime, Map forParamUseWrappers) {
+ work(poolExecutor, null, remainTime, forParamUseWrappers);
+ }
+
+ /**
+ * 总控制台超时,停止所有任务
+ */
+ public void stopNow() {
+ if (getState() == INIT || getState() == WORKING) {
+ fastFail(getState(), null);
+ }
+ }
+
+ /**
+ * 判断自己下游链路上,是否存在已经出结果的或已经开始执行的
+ * 如果没有返回true,如果有返回false
+ */
+ private boolean checkNextWrapperResult() {
+ //如果自己就是最后一个,或者后面有并行的多个,就返回true
+ if (nextWrappers == null || nextWrappers.size() != 1) {
+ return getState() == INIT;
+ }
+ WorkerWrapper nextWrapper = nextWrappers.get(0);
+ boolean state = nextWrapper.getState() == INIT;
+ //继续校验自己的next的状态
+ return state && nextWrapper.checkNextWrapperResult();
+ }
+
+ /**
+ * 进行下一个任务
+ */
+ private void beginNext(ThreadPoolExecutor poolExecutor, long now, long remainTime) {
+ //花费的时间
+ long costTime = SystemClock.now() - now;
+ if (nextWrappers == null) {
+ return;
+ }
+ if (nextWrappers.size() == 1) {
+ nextWrappers.get(0).work(poolExecutor, WorkerWrapper.this, remainTime - costTime, forParamUseWrappers);
+ return;
+ }
+ CompletableFuture[] futures = new CompletableFuture[nextWrappers.size()];
+ for (int i = 0; i < nextWrappers.size(); i++) {
+ int finalI = i;
+ futures[i] = CompletableFuture.runAsync(() -> nextWrappers.get(finalI)
+ .work(poolExecutor, WorkerWrapper.this, remainTime - costTime, forParamUseWrappers), poolExecutor);
+ }
+ try {
+ CompletableFuture.allOf(futures).get();
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void doDependsOneJob(WorkerWrapper dependWrapper) {
+ if (ResultState.TIMEOUT == dependWrapper.getWorkResult().getResultState()) {
+ workResult = defaultResult();
+ fastFail(INIT, null);
+ } else if (ResultState.EXCEPTION == dependWrapper.getWorkResult().getResultState()) {
+ workResult = defaultExResult(dependWrapper.getWorkResult().getEx());
+ fastFail(INIT, null);
+ } else {
+ //前面任务正常完毕了,该自己了
+ fire();
+ }
+ }
+
+ private synchronized void doDependsJobs(ThreadPoolExecutor poolExecutor, List dependWrappers, WorkerWrapper fromWrapper, long now, long remainTime) {
+ boolean nowDependIsMust = false;
+ //创建必须完成的上游wrapper集合
+ Set mustWrapper = new HashSet<>();
+ for (DependWrapper dependWrapper : dependWrappers) {
+ if (dependWrapper.isMust()) {
+ mustWrapper.add(dependWrapper);
+ }
+ if (dependWrapper.getDependWrapper().equals(fromWrapper)) {
+ nowDependIsMust = dependWrapper.isMust();
+ }
+ }
+
+ //如果全部是不必须的条件,那么只要到了这里,就执行自己。
+ if (mustWrapper.size() == 0) {
+ if (ResultState.TIMEOUT == fromWrapper.getWorkResult().getResultState()) {
+ fastFail(INIT, null);
+ } else {
+ fire();
+ }
+ beginNext(poolExecutor, now, remainTime);
+ return;
+ }
+
+ //如果存在需要必须完成的,且fromWrapper不是必须的,就什么也不干
+ if (!nowDependIsMust) {
+ return;
+ }
+
+ //如果fromWrapper是必须的
+ boolean existNoFinish = false;
+ boolean hasError = false;
+ //先判断前面必须要执行的依赖任务的执行结果,如果有任何一个失败,那就不用走action了,直接给自己设置为失败,进行下一步就是了
+ for (DependWrapper dependWrapper : mustWrapper) {
+ WorkerWrapper workerWrapper = dependWrapper.getDependWrapper();
+ WorkResult tempWorkResult = workerWrapper.getWorkResult();
+ //为null或者isWorking,说明它依赖的某个任务还没执行到或没执行完
+ if (workerWrapper.getState() == INIT || workerWrapper.getState() == WORKING) {
+ existNoFinish = true;
+ break;
+ }
+ if (ResultState.TIMEOUT == tempWorkResult.getResultState()) {
+ workResult = defaultResult();
+ hasError = true;
+ break;
+ }
+ if (ResultState.EXCEPTION == tempWorkResult.getResultState()) {
+ workResult = defaultExResult(workerWrapper.getWorkResult().getEx());
+ hasError = true;
+ break;
+ }
+
+ }
+ //只要有失败的
+ if (hasError) {
+ fastFail(INIT, null);
+ beginNext(poolExecutor, now, remainTime);
+ return;
+ }
+
+ //如果上游都没有失败,分为两种情况,一种是都finish了,一种是有的在working
+ //都finish的话
+ if (!existNoFinish) {
+ //上游都finish了,进行自己
+ fire();
+ beginNext(poolExecutor, now, remainTime);
+ }
+ }
+
+ /**
+ * 执行自己的job.具体的执行是在另一个线程里,但判断阻塞超时是在work线程
+ */
+ private void fire() {
+ //阻塞取结果
+ workResult = workerDoJob();
+ }
+
+ /**
+ * 快速失败
+ */
+ private boolean fastFail(int expect, Exception e) {
+ //试图将它从expect状态,改成Error
+ if (!compareAndSetState(expect, ERROR)) {
+ return false;
+ }
+
+ //尚未处理过结果
+ if (checkIsNullResult()) {
+ if (e == null) {
+ workResult = defaultResult();
+ } else {
+ workResult = defaultExResult(e);
+ }
+ }
+
+ callback.result(false, param, workResult);
+ return true;
+ }
+
+ /**
+ * 具体的单个worker执行任务
+ */
+ private WorkResult workerDoJob() {
+ //避免重复执行
+ if (!checkIsNullResult()) {
+ return workResult;
+ }
+ try {
+ //如果已经不是init状态了,说明正在被执行或已执行完毕。这一步很重要,可以保证任务不被重复执行
+ if (!compareAndSetState(INIT, WORKING)) {
+ return workResult;
+ }
+
+ callback.begin();
+
+ //执行耗时操作
+ V resultValue = worker.action(param, forParamUseWrappers);
+
+ //如果状态不是在working,说明别的地方已经修改了
+ if (!compareAndSetState(WORKING, FINISH)) {
+ return workResult;
+ }
+
+ workResult.setResultState(ResultState.SUCCESS);
+ workResult.setResult(resultValue);
+ //回调成功
+ callback.result(true, param, workResult);
+
+ return workResult;
+ } catch (Exception e) {
+ //避免重复回调
+ if (!checkIsNullResult()) {
+ return workResult;
+ }
+ fastFail(WORKING, e);
+ return workResult;
+ }
+ }
+
+ public WorkResult getWorkResult() {
+ return workResult;
+ }
+
+ public List> getNextWrappers() {
+ return nextWrappers;
+ }
+
+ public void setParam(T param) {
+ this.param = param;
+ }
+
+ private boolean checkIsNullResult() {
+ return ResultState.DEFAULT == workResult.getResultState();
+ }
+
+ private void addDepend(WorkerWrapper, ?> workerWrapper, boolean must) {
+ addDepend(new DependWrapper(workerWrapper, must));
+ }
+
+ private void addDepend(DependWrapper dependWrapper) {
+ if (dependWrappers == null) {
+ dependWrappers = new ArrayList<>();
+ }
+ //如果依赖的是重复的同一个,就不重复添加了
+ for (DependWrapper wrapper : dependWrappers) {
+ if (wrapper.equals(dependWrapper)) {
+ return;
+ }
+ }
+ dependWrappers.add(dependWrapper);
+ }
+
+ private void addNext(WorkerWrapper, ?> workerWrapper) {
+ if (nextWrappers == null) {
+ nextWrappers = new ArrayList<>();
+ }
+ //避免添加重复
+ for (WorkerWrapper wrapper : nextWrappers) {
+ if (workerWrapper.equals(wrapper)) {
+ return;
+ }
+ }
+ nextWrappers.add(workerWrapper);
+ }
+
+ private void addNextWrappers(List> wrappers) {
+ if (wrappers == null) {
+ return;
+ }
+ for (WorkerWrapper, ?> wrapper : wrappers) {
+ addNext(wrapper);
+ }
+ }
+
+ private void addDependWrappers(List dependWrappers) {
+ if (dependWrappers == null) {
+ return;
+ }
+ for (DependWrapper wrapper : dependWrappers) {
+ addDepend(wrapper);
+ }
+ }
+
+ private WorkResult defaultResult() {
+ workResult.setResultState(ResultState.TIMEOUT);
+ workResult.setResult(worker.defaultValue());
+ return workResult;
+ }
+
+ private WorkResult defaultExResult(Exception ex) {
+ workResult.setResultState(ResultState.EXCEPTION);
+ workResult.setResult(worker.defaultValue());
+ workResult.setEx(ex);
+ return workResult;
+ }
+
+
+ private int getState() {
+ return state.get();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ private boolean compareAndSetState(int expect, int update) {
+ return this.state.compareAndSet(expect, update);
+ }
+
+ private void setNeedCheckNextWrapperResult(boolean needCheckNextWrapperResult) {
+ this.needCheckNextWrapperResult = needCheckNextWrapperResult;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ WorkerWrapper, ?> that = (WorkerWrapper, ?>) o;
+ return needCheckNextWrapperResult == that.needCheckNextWrapperResult &&
+ Objects.equals(param, that.param) &&
+ Objects.equals(worker, that.worker) &&
+ Objects.equals(callback, that.callback) &&
+ Objects.equals(nextWrappers, that.nextWrappers) &&
+ Objects.equals(dependWrappers, that.dependWrappers) &&
+ Objects.equals(state, that.state) &&
+ Objects.equals(workResult, that.workResult);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(param, worker, callback, nextWrappers, dependWrappers, state, workResult, needCheckNextWrapperResult);
+ }
+
+ public static class Builder {
+ /**
+ * 该wrapper的唯一标识
+ */
+ private String id = UUID.randomUUID().toString();
+ /**
+ * worker将来要处理的param
+ */
+ private W param;
+ private IWorker worker;
+ private ICallback callback;
+ /**
+ * 自己后面的所有
+ */
+ private List> nextWrappers;
+ /**
+ * 自己依赖的所有
+ */
+ private List dependWrappers;
+ /**
+ * 存储强依赖于自己的wrapper集合
+ */
+ private Set> selfIsMustSet;
+
+ private boolean needCheckNextWrapperResult = true;
+
+ public Builder worker(IWorker worker) {
+ this.worker = worker;
+ return this;
+ }
+
+ public Builder param(W w) {
+ this.param = w;
+ return this;
+ }
+
+ public Builder id(String id) {
+ if (id != null) {
+ this.id = id;
+ }
+ return this;
+ }
+
+ public Builder needCheckNextWrapperResult(boolean needCheckNextWrapperResult) {
+ this.needCheckNextWrapperResult = needCheckNextWrapperResult;
+ return this;
+ }
+
+ public Builder callback(ICallback callback) {
+ this.callback = callback;
+ return this;
+ }
+
+ public Builder depend(WorkerWrapper, ?>... wrappers) {
+ if (wrappers == null) {
+ return this;
+ }
+ for (WorkerWrapper, ?> wrapper : wrappers) {
+ depend(wrapper);
+ }
+ return this;
+ }
+
+ public Builder depend(WorkerWrapper, ?> wrapper) {
+ return depend(wrapper, true);
+ }
+
+ public Builder depend(WorkerWrapper, ?> wrapper, boolean isMust) {
+ if (wrapper == null) {
+ return this;
+ }
+ DependWrapper dependWrapper = new DependWrapper(wrapper, isMust);
+ if (dependWrappers == null) {
+ dependWrappers = new ArrayList<>();
+ }
+ dependWrappers.add(dependWrapper);
+ return this;
+ }
+
+ public Builder next(WorkerWrapper, ?> wrapper) {
+ return next(wrapper, true);
+ }
+
+ public Builder next(WorkerWrapper, ?> wrapper, boolean selfIsMust) {
+ if (nextWrappers == null) {
+ nextWrappers = new ArrayList<>();
+ }
+ nextWrappers.add(wrapper);
+
+ //强依赖自己
+ if (selfIsMust) {
+ if (selfIsMustSet == null) {
+ selfIsMustSet = new HashSet<>();
+ }
+ selfIsMustSet.add(wrapper);
+ }
+ return this;
+ }
+
+ public Builder next(WorkerWrapper, ?>... wrappers) {
+ if (wrappers == null) {
+ return this;
+ }
+ for (WorkerWrapper, ?> wrapper : wrappers) {
+ next(wrapper);
+ }
+ return this;
+ }
+
+ public WorkerWrapper build() {
+ WorkerWrapper wrapper = new WorkerWrapper<>(id, worker, param, callback);
+ wrapper.setNeedCheckNextWrapperResult(needCheckNextWrapperResult);
+ if (dependWrappers != null) {
+ for (DependWrapper workerWrapper : dependWrappers) {
+ workerWrapper.getDependWrapper().addNext(wrapper);
+ wrapper.addDepend(workerWrapper);
+ }
+ }
+ if (nextWrappers != null) {
+ for (WorkerWrapper, ?> workerWrapper : nextWrappers) {
+ boolean must = false;
+ if (selfIsMustSet != null && selfIsMustSet.contains(workerWrapper)) {
+ must = true;
+ }
+ workerWrapper.addDepend(wrapper, must);
+ wrapper.addNext(workerWrapper);
+ }
+ }
+
+ return wrapper;
+ }
+
+ }
+}
diff --git a/asyncTool/src/test/java/depend/DeWorker.java b/asyncTool/src/test/java/depend/DeWorker.java
new file mode 100755
index 0000000..e963816
--- /dev/null
+++ b/asyncTool/src/test/java/depend/DeWorker.java
@@ -0,0 +1,42 @@
+package depend;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class DeWorker implements IWorker, ICallback {
+
+ @Override
+ public User action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return new User("user0");
+ }
+
+
+ @Override
+ public User defaultValue() {
+ return new User("default User");
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ System.out.println("worker0 的结果是:" + workResult.getResult());
+ }
+
+}
diff --git a/asyncTool/src/test/java/depend/DeWorker1.java b/asyncTool/src/test/java/depend/DeWorker1.java
new file mode 100755
index 0000000..6cafc30
--- /dev/null
+++ b/asyncTool/src/test/java/depend/DeWorker1.java
@@ -0,0 +1,43 @@
+package depend;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class DeWorker1 implements IWorker, User>, ICallback, User> {
+
+ @Override
+ public User action(WorkResult result, Map allWrappers) {
+ System.out.println("par1的入参来自于par0: " + result.getResult());
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return new User("user1");
+ }
+
+
+ @Override
+ public User defaultValue() {
+ return new User("default User");
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, WorkResult param, WorkResult workResult) {
+ System.out.println("worker1 的结果是:" + workResult.getResult());
+ }
+
+}
diff --git a/asyncTool/src/test/java/depend/DeWorker2.java b/asyncTool/src/test/java/depend/DeWorker2.java
new file mode 100755
index 0000000..3dd73e7
--- /dev/null
+++ b/asyncTool/src/test/java/depend/DeWorker2.java
@@ -0,0 +1,43 @@
+package depend;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class DeWorker2 implements IWorker, String>, ICallback, String> {
+
+ @Override
+ public String action(WorkResult result, Map allWrappers) {
+ System.out.println("par2的入参来自于par1: " + result.getResult());
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return result.getResult().getName();
+ }
+
+
+ @Override
+ public String defaultValue() {
+ return "default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, WorkResult param, WorkResult workResult) {
+ System.out.println("worker2 的结果是:" + workResult.getResult());
+ }
+
+}
diff --git a/asyncTool/src/test/java/depend/LambdaTest.java b/asyncTool/src/test/java/depend/LambdaTest.java
new file mode 100644
index 0000000..e4df734
--- /dev/null
+++ b/asyncTool/src/test/java/depend/LambdaTest.java
@@ -0,0 +1,74 @@
+package depend;
+
+import com.jd.platform.async.executor.Async;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author sjsdfg
+ * @since 2020/6/14
+ */
+public class LambdaTest {
+ public static void main(String[] args) throws Exception {
+ WorkerWrapper, String> workerWrapper2 = new WorkerWrapper.Builder, String>()
+ .worker((WorkResult result, Map allWrappers) -> {
+ System.out.println("par2的入参来自于par1: " + result.getResult());
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return result.getResult().getName();
+ })
+ .callback((boolean success, WorkResult param, WorkResult workResult) ->
+ System.out.println(String.format("thread is %s, param is %s, result is %s", Thread.currentThread().getName(), param, workResult)))
+ .id("third")
+ .build();
+
+ WorkerWrapper, User> workerWrapper1 = new WorkerWrapper.Builder, User>()
+ .worker((WorkResult result, Map allWrappers) -> {
+ System.out.println("par1的入参来自于par0: " + result.getResult());
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return new User("user1");
+ })
+ .callback((boolean success, WorkResult param, WorkResult workResult) ->
+ System.out.println(String.format("thread is %s, param is %s, result is %s", Thread.currentThread().getName(), param, workResult)))
+ .id("second")
+ .next(workerWrapper2)
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker((String object, Map allWrappers) -> {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return new User("user0");
+ })
+ .param("0")
+ .id("first")
+ .next(workerWrapper1, true)
+ .callback((boolean success, String param, WorkResult workResult) ->
+ System.out.println(String.format("thread is %s, param is %s, result is %s", Thread.currentThread().getName(), param, workResult)))
+ .build();
+
+ //虽然尚未执行,但是也可以先取得结果的引用,作为下一个任务的入参。V1.2前写法,需要手工给
+ //V1.3后,不用给wrapper setParam了,直接在worker的action里自行根据id获取即可.参考dependnew包下代码
+ WorkResult result = workerWrapper.getWorkResult();
+ WorkResult result1 = workerWrapper1.getWorkResult();
+ workerWrapper1.setParam(result);
+ workerWrapper2.setParam(result1);
+
+ Async.beginWork(3500, workerWrapper);
+
+ System.out.println(workerWrapper2.getWorkResult());
+ Async.shutDown();
+ }
+}
diff --git a/asyncTool/src/test/java/depend/Test.java b/asyncTool/src/test/java/depend/Test.java
new file mode 100644
index 0000000..971fdcf
--- /dev/null
+++ b/asyncTool/src/test/java/depend/Test.java
@@ -0,0 +1,55 @@
+package depend;
+
+import com.jd.platform.async.executor.Async;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.concurrent.ExecutionException;
+
+
+/**
+ * 后面请求依赖于前面请求的执行结果
+ * @author wuweifeng wrote on 2019-12-26
+ * @version 1.0
+ */
+public class Test {
+
+ public static void main(String[] args) throws ExecutionException, InterruptedException {
+ DeWorker w = new DeWorker();
+ DeWorker1 w1 = new DeWorker1();
+ DeWorker2 w2 = new DeWorker2();
+
+ WorkerWrapper, String> workerWrapper2 = new WorkerWrapper.Builder, String>()
+ .worker(w2)
+ .callback(w2)
+ .id("third")
+ .build();
+
+ WorkerWrapper, User> workerWrapper1 = new WorkerWrapper.Builder, User>()
+ .worker(w1)
+ .callback(w1)
+ .id("second")
+ .next(workerWrapper2)
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .param("0")
+ .id("first")
+ .next(workerWrapper1, true)
+ .callback(w)
+ .build();
+
+ //虽然尚未执行,但是也可以先取得结果的引用,作为下一个任务的入参。V1.2前写法,需要手工给
+ //V1.3后,不用给wrapper setParam了,直接在worker的action里自行根据id获取即可.参考dependnew包下代码
+ WorkResult result = workerWrapper.getWorkResult();
+ WorkResult result1 = workerWrapper1.getWorkResult();
+ workerWrapper1.setParam(result);
+ workerWrapper2.setParam(result1);
+
+ Async.beginWork(3500, workerWrapper);
+
+ System.out.println(workerWrapper2.getWorkResult());
+ Async.shutDown();
+ }
+}
diff --git a/asyncTool/src/test/java/depend/User.java b/asyncTool/src/test/java/depend/User.java
new file mode 100644
index 0000000..dfd6277
--- /dev/null
+++ b/asyncTool/src/test/java/depend/User.java
@@ -0,0 +1,29 @@
+package depend;
+
+/**
+ * 一个包装类
+ * @author wuweifeng wrote on 2019-12-26
+ * @version 1.0
+ */
+public class User {
+ private String name;
+
+ public User(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+}
diff --git a/asyncTool/src/test/java/dependnew/DeWorker.java b/asyncTool/src/test/java/dependnew/DeWorker.java
new file mode 100755
index 0000000..6ae011f
--- /dev/null
+++ b/asyncTool/src/test/java/dependnew/DeWorker.java
@@ -0,0 +1,42 @@
+package dependnew;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class DeWorker implements IWorker, ICallback {
+
+ @Override
+ public User action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return new User("user0");
+ }
+
+
+ @Override
+ public User defaultValue() {
+ return new User("default User");
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ System.out.println("worker0 的结果是:" + workResult.getResult());
+ }
+
+}
diff --git a/asyncTool/src/test/java/dependnew/DeWorker1.java b/asyncTool/src/test/java/dependnew/DeWorker1.java
new file mode 100755
index 0000000..0a56fdf
--- /dev/null
+++ b/asyncTool/src/test/java/dependnew/DeWorker1.java
@@ -0,0 +1,45 @@
+package dependnew;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class DeWorker1 implements IWorker, ICallback {
+
+ @Override
+ public User action(String object, Map allWrappers) {
+ System.out.println("-----------------");
+ System.out.println("获取par0的执行结果: " + allWrappers.get("first").getWorkResult());
+ System.out.println("取par0的结果作为自己的入参,并将par0的结果加上一些东西");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ User user0 = (User) allWrappers.get("first").getWorkResult().getResult();
+ return new User(user0.getName() + " worker1 add");
+ }
+
+ @Override
+ public User defaultValue() {
+ return new User("default User");
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ System.out.println("worker1 的结果是:" + workResult.getResult());
+ }
+
+}
diff --git a/asyncTool/src/test/java/dependnew/DeWorker2.java b/asyncTool/src/test/java/dependnew/DeWorker2.java
new file mode 100755
index 0000000..c4f61bc
--- /dev/null
+++ b/asyncTool/src/test/java/dependnew/DeWorker2.java
@@ -0,0 +1,45 @@
+package dependnew;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class DeWorker2 implements IWorker, ICallback {
+
+ @Override
+ public String action(User object, Map allWrappers) {
+ System.out.println("-----------------");
+ System.out.println("par1的执行结果是: " + allWrappers.get("second").getWorkResult());
+ System.out.println("取par1的结果作为自己的入参,并将par1的结果加上一些东西");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ User user1 = (User) allWrappers.get("second").getWorkResult().getResult();
+ return user1.getName() + " worker2 add";
+ }
+
+ @Override
+ public String defaultValue() {
+ return "default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, User param, WorkResult workResult) {
+ System.out.println("worker2 的结果是:" + workResult.getResult());
+ }
+
+}
diff --git a/asyncTool/src/test/java/dependnew/Test.java b/asyncTool/src/test/java/dependnew/Test.java
new file mode 100644
index 0000000..731e42b
--- /dev/null
+++ b/asyncTool/src/test/java/dependnew/Test.java
@@ -0,0 +1,49 @@
+package dependnew;
+
+import com.jd.platform.async.executor.Async;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.concurrent.ExecutionException;
+
+
+/**
+ * 后面请求依赖于前面请求的执行结果
+ * @author wuweifeng wrote on 2019-12-26
+ * @version 1.0
+ */
+public class Test {
+
+ public static void main(String[] args) throws ExecutionException, InterruptedException {
+ DeWorker w = new DeWorker();
+ DeWorker1 w1 = new DeWorker1();
+ DeWorker2 w2 = new DeWorker2();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .id("third")
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .id("second")
+ .next(workerWrapper2)
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .param("0")
+ .id("first")
+ .next(workerWrapper1)
+ .callback(w)
+ .build();
+
+ //V1.3后,不用给wrapper setParam了,直接在worker的action里自行根据id获取即可
+
+ Async.beginWork(3500, workerWrapper);
+
+ System.out.println(workerWrapper2.getWorkResult());
+ Async.shutDown();
+ }
+}
diff --git a/asyncTool/src/test/java/dependnew/User.java b/asyncTool/src/test/java/dependnew/User.java
new file mode 100644
index 0000000..bbef801
--- /dev/null
+++ b/asyncTool/src/test/java/dependnew/User.java
@@ -0,0 +1,29 @@
+package dependnew;
+
+/**
+ * 一个包装类
+ * @author wuweifeng wrote on 2019-12-26
+ * @version 1.0
+ */
+public class User {
+ private String name;
+
+ public User(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+}
diff --git a/asyncTool/src/test/java/parallel/ParTimeoutWorker.java b/asyncTool/src/test/java/parallel/ParTimeoutWorker.java
new file mode 100755
index 0000000..7f7b9aa
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/ParTimeoutWorker.java
@@ -0,0 +1,49 @@
+package parallel;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class ParTimeoutWorker implements IWorker, ICallback {
+
+ @Override
+ public String action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "result = " + SystemClock.now() + "---param = " + object + " from 0";
+ }
+
+
+ @Override
+ public String defaultValue() {
+ return "worker0--default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ if (success) {
+ System.out.println("callback worker0 success--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ } else {
+ System.err.println("callback worker0 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ }
+ }
+
+}
diff --git a/asyncTool/src/test/java/parallel/ParWorker.java b/asyncTool/src/test/java/parallel/ParWorker.java
new file mode 100755
index 0000000..b174c51
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/ParWorker.java
@@ -0,0 +1,49 @@
+package parallel;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class ParWorker implements IWorker, ICallback {
+
+ @Override
+ public String action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "result = " + SystemClock.now() + "---param = " + object + " from 0";
+ }
+
+
+ @Override
+ public String defaultValue() {
+ return "worker0--default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ if (success) {
+ System.out.println("callback worker0 success--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ } else {
+ System.err.println("callback worker0 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ }
+ }
+
+}
diff --git a/asyncTool/src/test/java/parallel/ParWorker1.java b/asyncTool/src/test/java/parallel/ParWorker1.java
new file mode 100755
index 0000000..7f13081
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/ParWorker1.java
@@ -0,0 +1,53 @@
+package parallel;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class ParWorker1 implements IWorker, ICallback {
+ private long sleepTime = 1000;
+
+ public void setSleepTime(long sleepTime) {
+ this.sleepTime = sleepTime;
+ }
+
+ @Override
+ public String action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "result = " + SystemClock.now() + "---param = " + object + " from 1";
+ }
+
+ @Override
+ public String defaultValue() {
+ return "worker1--default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ if (success) {
+ System.out.println("callback worker1 success--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ } else {
+ System.err.println("callback worker1 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ }
+ }
+
+}
diff --git a/asyncTool/src/test/java/parallel/ParWorker2.java b/asyncTool/src/test/java/parallel/ParWorker2.java
new file mode 100755
index 0000000..0e89e45
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/ParWorker2.java
@@ -0,0 +1,54 @@
+package parallel;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class ParWorker2 implements IWorker, ICallback {
+ private long sleepTime = 1000;
+
+ public void setSleepTime(long sleepTime) {
+ this.sleepTime = sleepTime;
+ }
+
+ @Override
+ public String action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "result = " + SystemClock.now() + "---param = " + object + " from 2";
+ }
+
+
+ @Override
+ public String defaultValue() {
+ return "worker2--default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ if (success) {
+ System.out.println("callback worker2 success--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ } else {
+ System.err.println("callback worker2 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ }
+ }
+
+}
diff --git a/asyncTool/src/test/java/parallel/ParWorker3.java b/asyncTool/src/test/java/parallel/ParWorker3.java
new file mode 100755
index 0000000..4284b0f
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/ParWorker3.java
@@ -0,0 +1,53 @@
+package parallel;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class ParWorker3 implements IWorker, ICallback {
+ private long sleepTime = 1000;
+
+ public void setSleepTime(long sleepTime) {
+ this.sleepTime = sleepTime;
+ }
+ @Override
+ public String action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "result = " + SystemClock.now() + "---param = " + object + " from 3";
+ }
+
+
+ @Override
+ public String defaultValue() {
+ return "worker3--default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ if (success) {
+ System.out.println("callback worker3 success--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ } else {
+ System.err.println("callback worker3 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ }
+ }
+
+}
diff --git a/asyncTool/src/test/java/parallel/ParWorker4.java b/asyncTool/src/test/java/parallel/ParWorker4.java
new file mode 100755
index 0000000..723c5f2
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/ParWorker4.java
@@ -0,0 +1,49 @@
+package parallel;
+
+
+import com.jd.platform.async.callback.ICallback;
+import com.jd.platform.async.callback.IWorker;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.worker.WorkResult;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.Map;
+
+/**
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class ParWorker4 implements IWorker, ICallback {
+
+ @Override
+ public String action(String object, Map allWrappers) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "result = " + SystemClock.now() + "---param = " + object + " from 4";
+ }
+
+
+ @Override
+ public String defaultValue() {
+ return "worker4--default";
+ }
+
+ @Override
+ public void begin() {
+ //System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
+ }
+
+ @Override
+ public void result(boolean success, String param, WorkResult workResult) {
+ if (success) {
+ System.out.println("callback worker4 success--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ } else {
+ System.err.println("callback worker4 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ + "-threadName:" +Thread.currentThread().getName());
+ }
+ }
+
+}
diff --git a/asyncTool/src/test/java/parallel/TestPar.java b/asyncTool/src/test/java/parallel/TestPar.java
new file mode 100755
index 0000000..1c2accf
--- /dev/null
+++ b/asyncTool/src/test/java/parallel/TestPar.java
@@ -0,0 +1,868 @@
+package parallel;
+
+
+import com.jd.platform.async.executor.Async;
+import com.jd.platform.async.executor.timer.SystemClock;
+import com.jd.platform.async.wrapper.WorkerWrapper;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * 并行测试
+ *
+ * @author wuweifeng wrote on 2019-11-20.
+ */
+public class TestPar {
+ public static void main(String[] args) throws Exception {
+
+ testNormal();
+// testMulti();
+// testMultiReverse();
+// testMultiError2();
+// testMulti3();
+// testMulti3Reverse();
+// testMulti4();
+// testMulti4Reverse();
+// testMulti5();
+// testMulti5Reverse();
+// testMulti6();
+// testMulti7();
+// testMulti8();
+// testMulti9();
+// testMulti9Reverse();
+ }
+
+ /**
+ * 3个并行,测试不同时间的超时
+ */
+ private static void testNormal() throws InterruptedException, ExecutionException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ Async.beginWork(1500, workerWrapper, workerWrapper1, workerWrapper2);
+// Async.beginWork(800, workerWrapper, workerWrapper1, workerWrapper2);
+// Async.beginWork(1000, workerWrapper, workerWrapper1, workerWrapper2);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+ System.out.println(Async.getThreadCount());
+
+ System.out.println(workerWrapper.getWorkResult());
+ Async.shutDown();
+ }
+
+ /**
+ * 0,2同时开启,1在0后面
+ * 0---1
+ * 2
+ */
+ private static void testMulti() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper1)
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ Async.beginWork(2500, workerWrapper, workerWrapper2);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ Async.shutDown();
+ }
+
+ /**
+ * 0,2同时开启,1在0后面
+ * 0---1
+ * 2
+ */
+ private static void testMultiReverse() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .depend(workerWrapper)
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .build();
+
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ Async.beginWork(2500, workerWrapper, workerWrapper2);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ Async.shutDown();
+ }
+
+
+ /**
+ * 0,2同时开启,1在0后面. 组超时,则0和2成功,1失败
+ * 0---1
+ * 2
+ */
+ private static void testMultiError() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper1)
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ Async.beginWork(1500, workerWrapper, workerWrapper2);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ Async.shutDown();
+ }
+
+ /**
+ * 0执行完,同时1和2, 1\2都完成后3
+ * 1
+ * 0 3
+ * 2
+ */
+ private static void testMulti3() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+ ParWorker3 w3 = new ParWorker3();
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper1, workerWrapper2)
+ .build();
+
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ Async.beginWork(3100, workerWrapper);
+// Async.beginWork(2100, workerWrapper);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+ /**
+ * 0执行完,同时1和2, 1\2都完成后3
+ * 1
+ * 0 3
+ * 2
+ */
+ private static void testMulti3Reverse() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+ ParWorker3 w3 = new ParWorker3();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .depend(workerWrapper)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .depend(workerWrapper)
+ .build();
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .depend(workerWrapper1, workerWrapper2)
+ .build();
+
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ Async.beginWork(3100, workerWrapper);
+// Async.beginWork(2100, workerWrapper);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+
+ /**
+ * 0执行完,同时1和2, 1\2都完成后3,2耗时2秒,1耗时1秒。3会等待2完成
+ * 1
+ * 0 3
+ * 2
+ *
+ * 执行结果0,1,2,3
+ */
+ private static void testMulti4() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+
+ ParWorker2 w2 = new ParWorker2();
+ w2.setSleepTime(2000);
+
+ ParWorker3 w3 = new ParWorker3();
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper1, workerWrapper2)
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ //正常完毕
+ Async.beginWork(4100, workerWrapper);
+ //3会超时
+// Async.beginWork(3100, workerWrapper);
+ //2,3会超时
+// Async.beginWork(2900, workerWrapper);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+ /**
+ * 0执行完,同时1和2, 1\2都完成后3,2耗时2秒,1耗时1秒。3会等待2完成
+ * 1
+ * 0 3
+ * 2
+ *
+ * 执行结果0,1,2,3
+ */
+ private static void testMulti4Reverse() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+
+ ParWorker2 w2 = new ParWorker2();
+ w2.setSleepTime(2000);
+
+ ParWorker3 w3 = new ParWorker3();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .build();
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .depend(workerWrapper)
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .depend(workerWrapper)
+ .next(workerWrapper3)
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ //正常完毕
+ Async.beginWork(4100, workerWrapper);
+ //3会超时
+// Async.beginWork(3100, workerWrapper);
+ //2,3会超时
+// Async.beginWork(2900, workerWrapper);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+ /**
+ * 0执行完,同时1和2, 1\2 任何一个执行完后,都执行3
+ * 1
+ * 0 3
+ * 2
+ *
+ * 则结果是:
+ * 0,2,3,1
+ * 2,3分别是500、400.3执行完毕后,1才执行完
+ */
+ private static void testMulti5() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+
+ ParWorker2 w2 = new ParWorker2();
+ w2.setSleepTime(500);
+
+ ParWorker3 w3 = new ParWorker3();
+ w3.setSleepTime(400);
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .next(workerWrapper3, false)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .next(workerWrapper3, false)
+ .build();
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper1, workerWrapper2)
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ //正常完毕
+ Async.beginWork(4100, workerWrapper);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+
+ /**
+ * 0执行完,同时1和2, 1\2 任何一个执行完后,都执行3
+ * 1
+ * 0 3
+ * 2
+ *
+ * 则结果是:
+ * 0,2,3,1
+ * 2,3分别是500、400.3执行完毕后,1才执行完
+ */
+ private static void testMulti5Reverse() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+
+ ParWorker2 w2 = new ParWorker2();
+ w2.setSleepTime(500);
+
+ ParWorker3 w3 = new ParWorker3();
+ w3.setSleepTime(400);
+
+ WorkerWrapper workerWrapper = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .build();
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .depend(workerWrapper, true)
+ .next(workerWrapper3, false)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .depend(workerWrapper, true)
+ .next(workerWrapper3, false)
+ .build();
+
+
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ //正常完毕
+ Async.beginWork(4100, workerWrapper);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+ /**
+ * 0执行完,同时1和2, 必须1执行完毕后,才能执行3. 无论2是否领先1完毕,都要等1
+ * 1
+ * 0 3
+ * 2
+ *
+ * 则结果是:
+ * 0,2,1,3
+ *
+ * 2,3分别是500、400.2执行完了,1没完,那就等着1完毕,才能3
+ */
+ private static void testMulti6() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+
+ ParWorker2 w2 = new ParWorker2();
+ w2.setSleepTime(500);
+
+ ParWorker3 w3 = new ParWorker3();
+ w3.setSleepTime(400);
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .build();
+
+ //设置2不是必须,1是必须的
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrapper0 = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper2, workerWrapper1)
+ .build();
+
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ //正常完毕
+ Async.beginWork(4100, workerWrapper0);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+ /**
+ * 两个0并行,上面0执行完,同时1和2, 下面0执行完开始1,上面的 必须1、2执行完毕后,才能执行3. 最后必须2、3都完成,才能4
+ * 1
+ * 0 3
+ * 2 4
+ * ---------
+ * 0 1 2
+ *
+ * 则结果是:
+ * callback worker0 success--1577242870969----result = 1577242870968---param = 00 from 0-threadName:Thread-1
+ * callback worker0 success--1577242870969----result = 1577242870968---param = 0 from 0-threadName:Thread-0
+ * callback worker1 success--1577242871972----result = 1577242871972---param = 11 from 1-threadName:Thread-1
+ * callback worker1 success--1577242871972----result = 1577242871972---param = 1 from 1-threadName:Thread-2
+ * callback worker2 success--1577242871973----result = 1577242871973---param = 2 from 2-threadName:Thread-3
+ * callback worker2 success--1577242872975----result = 1577242872975---param = 22 from 2-threadName:Thread-1
+ * callback worker3 success--1577242872977----result = 1577242872977---param = 3 from 3-threadName:Thread-2
+ * callback worker4 success--1577242873980----result = 1577242873980---param = 4 from 3-threadName:Thread-2
+ */
+ private static void testMulti7() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ ParWorker2 w2 = new ParWorker2();
+ ParWorker3 w3 = new ParWorker3();
+ ParWorker4 w4 = new ParWorker4();
+
+ WorkerWrapper workerWrapper4 = new WorkerWrapper.Builder()
+ .worker(w4)
+ .callback(w4)
+ .param("4")
+ .build();
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("3")
+ .next(workerWrapper4)
+ .build();
+
+ //下面的2
+ WorkerWrapper workerWrapper22 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("22")
+ .next(workerWrapper4)
+ .build();
+
+ //下面的1
+ WorkerWrapper workerWrapper11 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("11")
+ .next(workerWrapper22)
+ .build();
+
+ //下面的0
+ WorkerWrapper workerWrapper00 = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("00")
+ .next(workerWrapper11)
+ .build();
+
+ //上面的1
+ WorkerWrapper workerWrapper1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("1")
+ .next(workerWrapper3)
+ .build();
+
+ //上面的2
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("2")
+ .next(workerWrapper3)
+ .build();
+
+ //上面的0
+ WorkerWrapper workerWrapper0 = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("0")
+ .next(workerWrapper1, workerWrapper2)
+ .build();
+
+ long now = SystemClock.now();
+ System.out.println("begin-" + now);
+
+ //正常完毕
+ Async.beginWork(4100, workerWrapper00, workerWrapper0);
+
+ System.out.println("end-" + SystemClock.now());
+ System.err.println("cost-" + (SystemClock.now() - now));
+
+ System.out.println(Async.getThreadCount());
+ Async.shutDown();
+ }
+
+ /**
+ * a1 -> b -> c
+ * a2 -> b -> c
+ *
+ * b、c
+ */
+ private static void testMulti8() throws ExecutionException, InterruptedException {
+ ParWorker w = new ParWorker();
+ ParWorker1 w1 = new ParWorker1();
+ w1.setSleepTime(1005);
+
+ ParWorker2 w2 = new ParWorker2();
+ w2.setSleepTime(3000);
+ ParWorker3 w3 = new ParWorker3();
+ w3.setSleepTime(1000);
+
+ WorkerWrapper workerWrapper3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("c")
+ .build();
+
+ WorkerWrapper workerWrapper2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("b")
+ .next(workerWrapper3)
+ .build();
+
+ WorkerWrapper workerWrappera1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("a1")
+ .next(workerWrapper2)
+ .build();
+ WorkerWrapper workerWrappera2 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("a2")
+ .next(workerWrapper2)
+ .build();
+
+
+ Async.beginWork(6000, workerWrappera1, workerWrappera2);
+ Async.shutDown();
+ }
+
+ /**
+ * w1 -> w2 -> w3
+ * --- last
+ * w
+ * w1和w并行,w执行完后就执行last,此时b、c还没开始,b、c就不需要执行了
+ */
+ private static void testMulti9() throws ExecutionException, InterruptedException {
+ ParWorker1 w1 = new ParWorker1();
+ //注意这里,如果w1的执行时间比w长,那么w2和w3肯定不走。 如果w1和w执行时间一样长,多运行几次,会发现w2有时走有时不走
+// w1.setSleepTime(1100);
+
+ ParWorker w = new ParWorker();
+ ParWorker2 w2 = new ParWorker2();
+ ParWorker3 w3 = new ParWorker3();
+ ParWorker4 w4 = new ParWorker4();
+
+ WorkerWrapper last = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("last")
+ .build();
+
+ WorkerWrapper wrapperW = new WorkerWrapper.Builder()
+ .worker(w)
+ .callback(w)
+ .param("w")
+ .next(last, false)
+ .build();
+
+ WorkerWrapper wrapperW3 = new WorkerWrapper.Builder()
+ .worker(w3)
+ .callback(w3)
+ .param("w3")
+ .next(last, false)
+ .build();
+
+ WorkerWrapper wrapperW2 = new WorkerWrapper.Builder()
+ .worker(w2)
+ .callback(w2)
+ .param("w2")
+ .next(wrapperW3)
+ .build();
+
+ WorkerWrapper wrapperW1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("w1")
+ .next(wrapperW2)
+ .build();
+
+ Async.beginWork(6000, wrapperW, wrapperW1);
+ Async.shutDown();
+ }
+
+ /**
+ * w1 -> w2 -> w3
+ * --- last
+ * w
+ * w1和w并行,w执行完后就执行last,此时b、c还没开始,b、c就不需要执行了
+ */
+ private static void testMulti9Reverse() throws ExecutionException, InterruptedException {
+ ParWorker1 w1 = new ParWorker1();
+ //注意这里,如果w1的执行时间比w长,那么w2和w3肯定不走。 如果w1和w执行时间一样长,多运行几次,会发现w2有时走有时不走
+// w1.setSleepTime(1100);
+
+ ParWorker w = new ParWorker();
+ ParWorker2 w2 = new ParWorker2();
+ ParWorker3 w3 = new ParWorker3();
+ ParWorker4 w4 = new ParWorker4();
+
+ WorkerWrapper wrapperW1 = new WorkerWrapper.Builder()
+ .worker(w1)
+ .callback(w1)
+ .param("w1")
+ .build();
+
+ WorkerWrapper