有一个这种场景,教师管理3个小组,要各小组长收集小组内同学的成绩,然后汇总到教师那儿。
需要汇总3次,各个小组长也要收集3次。
并且每次汇集后要等教师检查后才汇总下一次成绩现在汇总一次的时候是可以的,用cyclcbarrier来控制,
但是汇总完毕后,如何开始下一次汇总呢?我试着用cyclebarrier的reset等方法    都失败了。下面是测试片段,Group是小组长,他负责收集和提交信息。
汇总完毕后打印一个“汇总和阅读完毕”
那么我如何保证在这之后,再开始一次汇总?
final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable() {
public void run() {
System.out.println("汇总并阅读完毕!");
}
}); for (int i = 0; i < 3; i++) {
Thread t=new Thread(new Group(i, barrier));
t.start();
}

解决方案 »

  1.   

    package com.linkage.olcom.thread.day11;import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;public class CyclicBarrierTest { /**
     * @param args
     */
    public static void main(String[] args) {
    int threadNum = 3;
    final CyclicBarrier barrier = new CyclicBarrier(threadNum+1, new Runnable() {
    public void run() {
    System.out.println("汇总并阅读完毕!");
    }
    });
    for (int i = 0; i < threadNum; i++) {
    Thread t=new Thread(new Group(i, barrier));
    t.start();
    }
    try {
    barrier.await(); //第一次
    barrier.await(); //第二次
    barrier.await(); //第三次
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (BrokenBarrierException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }}class Group implements Runnable {

    private int num;
    private CyclicBarrier barrier;

    public Group(int num,CyclicBarrier barrier) {
    super();
    this.barrier = barrier;
    this.num = num;
    } public void run() {
    for (int i = 1; i <= 3; i++) {
    try {
    System.out.println("组长"+i+":收集第" + "次完毕。");
    barrier.await();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (BrokenBarrierException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }}
      

  2.   

    package com.linkage.olcom.thread.day11;import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;public class CyclicBarrierTest { /**
     * @param args
     */
    public static void main(String[] args) {
    int threadNum = 3;
    final CyclicBarrier barrier = new CyclicBarrier(threadNum+1, new Runnable() {
    public void run() {
    System.out.println("汇总并阅读完毕!");
    }
    });
    for (int i = 1; i <= threadNum; i++) {
    Thread t=new Thread(new Group(barrier),"组长"+i);
    t.start();
    }
    try {
    barrier.await(); //第一次
    barrier.await(); //第二次
    barrier.await(); //第三次
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (BrokenBarrierException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }}class Group implements Runnable {

    private CyclicBarrier barrier;

    public Group(CyclicBarrier barrier) {
    super();
    this.barrier = barrier;
    } public void run() {
    for (int i = 1; i <= 3; i++) {
    try {
    System.out.println("组长"+Thread.currentThread().getName()+":收集第"+ i + "次完毕。");
    barrier.await();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (BrokenBarrierException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }}改了一些,基本功能实现了,呵呵。
      

  3.   

    多谢回复,那么我有几个不明白的地方,请问:
    1、main方法中为什么要barrier.await()?
    API中说参与者调用await。您这里是手误吗?不加这三个句子也可执行啊。
    2、run方法中的for循环中,每一次循环是一个公共屏障点吗?
    为什么是不同线程的  每次[color=#993366]循环会互相等待[/color]呢?  
    即每个组的第一次收集作为第一次循环,第二次收集作为第二次循环,
    各个组的第一次循环互相等待,第二次循环互相等待。
      

  4.   

    1、main方法中为什么要barrier.await()?呵呵,main是主线程,也就是进程的起点,没有手误的,也就是每次屏障结束,你可以在主线程来一个汇总。2、run方法中的for循环中,每一次循环是一个公共屏障点吗?CyclicBarrier在初始化时如下比如:
    final CyclicBarrier barrier = new CyclicBarrier(5);
    上面初始化是5,也就是必须满足对于这个屏障的引用每一轮达到5个barrier.await();就会执行,它不会管外界程序怎么调用await方法,具体你详细看JDK1.5API。其中和CyclicBarrier类似的功能的还有个CountDownLatch,你可以看看2者区别,至于你说的为什么各个线程会互相等待,那要看JDK源码了。。