java-如何为两个不同的任务集正确使用CyclicBarrier的循环行为?

当最后一个线程进入屏障时,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可以在完成后立即单独停止,并且不必都在停止之前彼此等待.

上一篇:基于docker安装mysql数据库


下一篇:Java 1.4同步:仅允许方法的一个实例运行(非阻塞)?