首页 \ 问答 \ 如何正确使用CyclicBarrier的循环行为来完成两组不同的任务?(How to properly use cyclic behaviour of CyclicBarrier for two different set of tasks?)

如何正确使用CyclicBarrier的循环行为来完成两组不同的任务?(How to properly use cyclic behaviour of CyclicBarrier for two different set of tasks?)

当最后一个线程进入屏障时,CyclicBarrier执行屏障操作。

如果在CyclicBarrier中定义了5个派对(线程),那么当第5个线程(任务)进入屏障时,屏障将跳闸(即将重置)并且屏障操作将被执行。

在这里,第五个线程是什么类型并不重要。 这可能是任何任务。

所以,我的问题是:

  1. 如果有两组任务(每个5个线程),那么如何确保首先执行一组特定的任务,然后执行barrier action命令。 剩下的一组任务在此之后执行,然后再次执行barrier action命令。

  2. 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

我期望的行为是首先执行所有验证任务,然后执行服务任务。

谢谢你的帮助。


CyclicBarrier executes the barrier action when the last thread enters the barrier.

If there are 5 parties(threads) defined in CyclicBarrier, then when 5th thread(task) will enter the barrier, the barrier will trip (i.e. will reset) and barrier action will get executed.

Here, it does not matter 5th thread is of what type. It could be any task.

So, my questions are:

  1. If there are two set of tasks (each of 5 thread), then how to make sure a particular set of tasks gets executed first and then barrier action command gets executed. And the remaining set of tasks gets executed after that and then again barrier action command gets executed.

  2. Whether CyclicBarrier is suitable for these kinds of scenarios or not. If not then how its cyclic behavior can be used properly in real-world scenarios.

Following is the CyclicBarrier code.

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();
        }

    }

}

Output of above task:

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

Behaviour I am expecting is that all validation tasks should be executed first, and thereafter service task should be executed.

Thanks for your help.


原文:https://stackoverflow.com/questions/48430960
更新时间:2024-03-25 20:03

最满意答案

最终HTML中生成的ID不保证与您的aspx源中的ID保持一致。 当您将控件放在命名容器中时,ID将在前面添加一个或多个父ID以确保其唯一性。 ClientId属性将始终为您提供ID属性的最终形式,因为它最终在HTML中,因此始终建议您在javascript中使用它。


The ID generated in the final HTML is not guaranteed to remain the same as the one in your aspx source. When you'll put the controls inside naming containers the ID will have prepended one or several parent ids to ensure its uniqueness. The ClientId property will always give you the final form of the ID attribute as it ends up in the HTML so it's always recommended to use that in your javascript.

相关问答

更多
  • 据我所知,有两种方法可以实现您的目标。 使用asp:ImageButton服务器控件并使用OnItemDataBound事件连接onclick客户端事件,或者只使用控件并内联ClientID 。 以下示例显示了这两种方法: <%@ Page Language="C#" AutoEventWireup="true" %>
  • 尝试这个