4

我有一个需要由三方填充的列表(线程,可以说)。我正在使用循环障碍来实现此功能。一切正常,除了我无法在不引起强制睡眠的情况下使用结果列表。下面是代码:

public class Test{

List<Integer> item = new Vector<Integer>();

public void returnTheList(){
       CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {

                @Override
                public void run() {

                    System.out.println("All parties are arrived at barrier, lets play -- : " + CyclicBarrierTest.getTheList().size());
                    //Here I am able to access my resulted list

                }
            });


            CyclicBarrierTest sw1 = new CyclicBarrierTest(cb, new ZetaCode(1500), s);
            CyclicBarrierTest sw2 = new CyclicBarrierTest(cb, new ZetaCode(1500),s);
            CyclicBarrierTest sw3 = new CyclicBarrierTest(cb, new ZetaCode(1500),s);
            Thread th1 = new Thread(sw1, "ZetaCode1");
            Thread th2 = new Thread(sw2, "ZetaCode2");
            Thread th3 = new Thread(sw3, "ZetaCode3");
            th1.start();
            th2.start();
            th3.start();

    }

public static void main(String args[]){
    System.out.println("asdfasd");
    Test test = new Test();
    //ActionClass ac = new ActionClass();
    test.returnTheList();
    System.out.println("Inside the main method...size of the final list : " +test.item.size() );
}

下面是我的 CyclicBrrierTest 课程:

public class CyclicBarrierTest implements Runnable{

private CyclicBarrier barrier;
private Object obj;
 static volatile String s = "";
 volatile List<Integer> finalIntList = new Vector<Integer>();

public CyclicBarrierTest(CyclicBarrier barrier, Object obj, String s){
    this.barrier = barrier;
    this.obj = obj;
}

@Override
public void run(){
    try{
        System.out.println(Thread.currentThread().getName() + " is waiting on barrier and s is now  : " + finalIntList.size());
        ZetaCode simple = (ZetaCode)obj;

        finalIntList.addAll(simple.getTheItemList());
        barrier.await();

        System.out.println(Thread.currentThread().getName() + " has crossed the barrier");

    }catch(InterruptedException ex){
        System.out.println("Error.." + ex.getMessage());

    }catch(Exception e){
        System.out.println("Error.." + e.getMessage());
    }
}
    public  List<Integer> getTheList(){
    return finalIntList;
}

因此,如果我在没有任何延迟的情况下运行此代码,则我的 main 方法中的 print 语句将我的列表长度设为零,但是在给予适当的睡眠后,它会给我预期的输出。我想在没有任何延迟的情况下实现相同的目标。任何帮助,将不胜感激。提前致谢。

4

2 回答 2

5

看来您想在这里使用 a CountDownLatch,而不是 a CyclicBarrier。完全按预期工作 - 您的CyclicBarrier主要方法只是没有等待它被所有 3 个线程触发。当你给它一个 sleep 语句时,其他 3 个线程恰好在main再次唤醒之前完成。

当您需要工人在继续之前都到达相同的“检查点”时, ACyclicBarrier很有用N,并且工人自己是唯一关心的人。但是,您在N + 1这里有一个用户,即main线程,他想知道它们何时完成,并且CyclicBarrier不支持该用例。

请注意,当然您也可以同时使用它们。

于 2014-07-17T07:54:19.413 回答
0

在这段代码中,我们有 4 个任务。Task1、Task2、Task3 产生 int 值,Task4 将添加所有 int 值。Task4 在为 Task1、Task2、Task3 调用 await() 后等待生成值。当它们生成值时,它们调用 await() 方法,Task 4 将添加它们的值并打印 o/p 并调用 reset() 方法,因此屏障将重置。重置后,此过程将再次继续

package practice;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicbarrierExample {

    public static void main(String[] args) {

        CyclicBarrier c = new CyclicBarrier(4);
        Task1 t1 = new Task1(c);
        Task2 t2 = new Task2(c);
        Task3 t3 = new Task3(c);
        Task4 t4 = new Task4(c);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
 }


class Task1 extends Thread {
    CyclicBarrier c;
    static int t1 ;

    public Task1(CyclicBarrier c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true) {
            t1 = t1 + 1;
            try {
                c.await();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

class Task2 extends Thread {
    CyclicBarrier c;

    static int t2;

    public Task2(CyclicBarrier c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true) {
            t2 = t2 + 1;
            try {
                c.await();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

}

class Task3 extends Thread {
    CyclicBarrier c;
    static int t3;

    public Task3(CyclicBarrier c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true) {
            t3 = t3 + 1;
            try {
                c.await();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

}

class Task4 extends Thread {
    CyclicBarrier c;
     static int t4;
    static int count=0;

    public Task4(CyclicBarrier c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (count<10) {
            try {
                c.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            t4 = Task1.t1 + Task2.t2 + Task3.t3;
            System.out.println(t4);
            try {
                c.reset();
            } catch (Exception e) {
                System.out.println("yo");
            }
            count++;

        }
    }

}
于 2019-08-16T06:29:34.170 回答