我有一个列表,需要由三方填充(线程,让我们说)。我正在使用循环屏障来实现此功能。一切正常,但我不能在不引起强迫睡眠的情况下使用结果列表。以下是代码:
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语句给我的列表长度为零,但是在给出适当的睡眠后它给了我预期的输出。我希望实现相同的给予任何延迟。任何帮助将不胜感激。 提前谢谢。
答案 0 :(得分:5)
您似乎想要使用CountDownLatch
,而不是CyclicBarrier
。 CyclicBarrier
完全正常工作 - 你的主要方法就是不等待它被所有3个线程绊倒。当你给它一个sleep语句时,其他3个线程恰好在main
再次唤醒之前完成。
如果您需要CyclicBarrier
名工作人员在继续之前到达同一个“检查点”,并且工作人员自己是唯一关心的人,那么N
非常有用。但是,您在此处有N + 1
个用户,main
主题,想要知道他们何时完成,CyclicBarrier
不支持该用例。
注意,当然您也可以同时使用它们。
答案 1 :(得分:0)
在此代码中,我们有4个任务。 Task1,Task2,Task3产生int值,而Task4将添加所有int值。 Task4在调用await()来让Task1,Task2,Task3产生值后等待,当它们产生值时,它们会调用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++;
}
}
}