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

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语句会使我的列表长度为零,但是经过适当的睡眠后,它将为我提供预期的输出。我想不加延迟地实现相同的效果。任何帮助,将不胜感激。
提前致谢。

最佳答案

似乎您想在这里使用 CountDownLatch 而不是CyclicBarrierCyclicBarrier完全按照预期的方式工作-您的主要方法只是不等待3个线程都将其触发。当您给它一个sleep语句时,其他3个线程恰好在main再次唤醒之前完成。

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

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

10-04 11:48