多线程协作 CyclicBarrier 如何重复使用

sling2007 2011-04-02 10:28:33
有一个这种场景,教师管理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();
}
...全文
236 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sling2007 2011-04-06
  • 打赏
  • 举报
回复
清明节快乐

这么敬业,当然全部给你啊
suifeng736 2011-04-02
  • 打赏
  • 举报
回复
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();
}

}
}

}

改了一些,基本功能实现了,呵呵。
sling2007 2011-04-02
  • 打赏
  • 举报
回复
多谢楼上,我运行了,但结果和我说的有出入。
我想要的是:
组长1:收集第1次完毕。
组长2:收集第1次完毕。
组长3:收集第1次完毕。
汇总并阅读完毕!
组长1:收集第2次完毕。
组长2:收集第2次完毕。
组长3:收集第2次完毕。
汇总并阅读完毕!
组长1:收集第1次完毕。
组长2:收集第2次完毕。
组长3:收集第3次完毕。
汇总并阅读完毕!


而不是:
组长1:收集第1次完毕。
组长1:收集第2次完毕。
组长1:收集第3次完毕。
汇总并阅读完毕!
组长2:收集第1次完毕。
组长2:收集第2次完毕。
组长2:收集第3次完毕。
汇总并阅读完毕!
组长3:收集第1次完毕。
组长3:收集第2次完毕。
组长3:收集第3次完毕。
汇总并阅读完毕!
suifeng736 2011-04-02
  • 打赏
  • 举报
回复
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();
}

}
}

}
suifeng736 2011-04-02
  • 打赏
  • 举报
回复
楼主,感觉我解答的还不错,希望能给点分数给我哈,哈哈。。
suifeng736 2011-04-02
  • 打赏
  • 举报
回复
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源码了。。

sling2007 2011-04-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 suifeng736 的回复:]
main(){
.........
barrier.await(); //第一次
barrier.await(); //第二次
barrier.await(); //第三次
}
public class Group........{
public void run() {
for (int i = 1; i <= 3; i++) {
try {
System.out.println("组长"+Thread.currentThread().getName()+":收集第"+ i + "次完毕。");
barrier.await();
} .......
[/Quote]
多谢回复,那么我有几个不明白的地方,请问:
1、main方法中为什么要barrier.await()?
API中说参与者调用await。。。。。。。您这里是手误吗?不加这三个句子也可执行啊。
2、run方法中的for循环中,每一次循环是一个公共屏障点吗?
为什么是不同线程的 每次[color=#993366]循环会互相等待[/color]呢?
即每个组的第一次收集作为第一次循环,第二次收集作为第二次循环,
各个组的第一次循环互相等待,第二次循环互相等待。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧