继承自 CyclicAction 的子类需要 TaskBarrier 为每个任务设置不同的中止条件。从 CyclicAction 继承的子类需要重载 protected void compute() 方法,定义在 barrier 的每个步骤需要执行的动作。compute() 方法将被反复执行直到 barrier 的 isTerminated() 方法返回 True。TaskBarrier 的行为类似于 CyclicBarrier。下面,我们来看看如何使用 CyclicAction 的子类。
清单 6. 使用 CyclicAction 的子类
class ConcurrentPrint extends RecursiveAction {
protected void compute() {
TaskBarrier b = new TaskBarrier() {
protected boolean terminate(int cycle, int registeredParties) {
System.out.println("Cycle is " + cycle + ";"
+ registeredParties + " parties");
return cycle >= 10;
}
};
int n = 3;
CyclicAction[] actions = new CyclicAction[n];
for (int i = 0; i < n; ++i) {
final int index = i;
actions[i] = new CyclicAction(b) {
protected void compute() {
System.out.println("I'm working " + getCycle() + " "
+ index);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
for (int i = 0; i < n; ++i)
actions[i].fork();
for (int i = 0; i < n; ++i)
actions[i].join();
}
}
在 清单 6 中,CyclicAction[] 数组建立了三个任务,打印各自的工作次数和序号。而在 b.terminate() 方法中,我们设置的中止条件表示重复 10 次计算后中止。现在剩下的工作就是将 ConcurrentPrint 提交到 ForkJoinPool 了。我们可以在 ForkJoinPool 的构造函数中指定需要的线程数目,例如 ForkJoinPool(4) 就表明线程池包含 4 个线程。我们在一个 JUnit 的 test 方法中运行 ConcurrentPrint 的这个循环任务:
清单 7. 运行 ConcurrentPrint 循环任务
@Test
public void testBarrier () throws InterruptedException, ExecutionException {
ForkJoinTask fjt = new ConcurrentPrint();
ForkJoinPool fjpool = new ForkJoinPool(4);
fjpool.submit(fjt);
fjpool.shutdown();
}
文章来源于领测软件测试网 https://www.ltesting.net/