当最后一个线程进入屏障时,CyclicBarrier执行屏障动作.
如果在CyclicBarrier中定义了5个方(线程),则当第5个线程(任务)进入屏障时,屏障将跳闸(即将重置)并执行屏障动作.
在这里,第5个线程是什么类型都没有关系.它可以是任何任务.
因此,我的问题是:
>如果有两组任务(每组5个线程),那么如何确保首先执行一组特定的任务,然后执行屏障操作命令.
然后其余的任务集将被执行,然后屏障操作命令将再次被执行.
> CyclicBarrier是否适合这些情况.
如果不是,那么如何在现实情况下正确使用其循环行为.
以下是CyclicBarrier代码.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierSimpleExample {
static int barrierActionThreadCount;
public static void main(String[] args){
// 5 is the number of parties. So, when the 5th thread will enter the barrier, barrier gets tripped or reset and BarrierAction will be called.
final CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new BarrierAction(barrierActionThreadCount));
for(int i=0;i<5;i++){
Thread validationTask = new Thread(new ValidationTask(i, cyclicBarrier));
validationTask.start();
}
for(int i=0;i<5;i++){
Thread serviceTask = new Thread(new ServiceTask(i, cyclicBarrier));
serviceTask.start();
}
}
}
class BarrierAction implements Runnable{
private int barrierActionThreadCount;
public BarrierAction(int barrierActionThreadCount) {
this.barrierActionThreadCount=barrierActionThreadCount;
}
// Barrier action will execute when barrier is reached i.e. number of parties waiting got executed
// In this case, it will trip when 5 different threaValidationTaskds are called and then again its number of parties will reset to 5
@Override
public void run() {
this.barrierActionThreadCount++;
System.out.println("Barrier action thread got executed "+barrierActionThreadCount+" times");
}
}
class ValidationTask implements Runnable{
CyclicBarrier cyclicBarrier;
int threadNum;
public ValidationTask(int threadNum, CyclicBarrier cyclicBarrier) {
this.threadNum = threadNum;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
Thread.sleep(threadNum*1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Validation Task: Thread-"+threadNum+" got executed");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
class ServiceTask implements Runnable{
CyclicBarrier cyclicBarrier;
int threadNum;
public ServiceTask(int threadNum, CyclicBarrier cyclicBarrier) {
this.threadNum = threadNum;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("Service Task: Thread-"+threadNum+" got executed");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
以上任务的输出:
Validation Task: Thread-0 got executed
Service Task: Thread-1 got executed
Service Task: Thread-0 got executed
Service Task: Thread-4 got executed
Service Task: Thread-2 got executed
Service Task: Thread-3 got executed
Barrier action thread got executed 1 times
Validation Task: Thread-1 got executed
Validation Task: Thread-2 got executed
Validation Task: Thread-3 got executed
Validation Task: Thread-4 got executed
Barrier action thread got executed 2 times
我期望的行为是,应首先执行所有验证任务,然后再执行服务任务.
谢谢你的帮助.
解决方法:
您无需使用大小为5的障碍来控制10个线程.
您使用大小为5的屏障来控制5个线程,其中每个线程执行一系列操作,等待所有线程完成一个步骤,然后再继续下一步.
如果要启动10个线程,并让5个ServiceTask线程等待5个ValidationTask线程完成,请使用CountDownLatch
,将其同时分配给ValidationTask和ServiceTask.
然后,ServiceTask应该在开始处调用await(),ValidationTask应该在结束处调用countDown().
这样,在所有ValidationTask完成之前不会运行ServiceTask,并且ValidationTask可以在完成后立即单独停止,并且不必都在停止之前彼此等待.