我正面临一个循环障碍的问题,请查看下面的代码-
MeetingPoint1.java
public class MeetingPoint1 implements Runnable{
@Override
public void run() {
System.out.println(" MeetingPoint1 one cleared... ");
}
}MeetingPoint2.java
public class MeetingPoint2 implements Runnable{
@Override
public void run() {
System.out.println(" MeetingPoint Two cleared... ");
}
}VehicalRunnable.java
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @author chouhan_r
*
*/
public class VehicleRunnable implements Runnable {
private CyclicBarrier barrier1;
private CyclicBarrier barrier2;
public VehicleRunnable(CyclicBarrier barrier1, CyclicBarrier barrier2) {
this.barrier1 = barrier1;
this.barrier2 = barrier2;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +" Waiting at Meeting Point 1");
if(Thread.currentThread().getName().equalsIgnoreCase("Car")){
throw new RuntimeException("something weird happened");
}
barrier1.await();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +" Waiting at Meeting Point 2");
barrier2.await();
} catch(BrokenBarrierException | RuntimeException | InterruptedException e){
e.printStackTrace();
}
}
}CyclicBarrierMain.java
import java.util.concurrent.CyclicBarrier;
/**
* @author chouhan_r
*
*/
public class CyclicBarrierMain {
/**
* @param args
*/
public static void main(String[] args) {
MeetingPoint1 meetingPoint1 = new MeetingPoint1();
MeetingPoint2 meetingPoint2 = new MeetingPoint2();
CyclicBarrier barrier1 = new CyclicBarrier(3, meetingPoint1);
CyclicBarrier barrier2 = new CyclicBarrier(3, meetingPoint2);
VehicleRunnable car = new VehicleRunnable(barrier1, barrier2);
VehicleRunnable bike = new VehicleRunnable(barrier1, barrier2);
VehicleRunnable bus= new VehicleRunnable(barrier1, barrier2);
new Thread(car,"Car").start();
new Thread(bike,"Bike").start();
new Thread(bus,"Bus").start();
}
}当线程抛出一些异常时,所有其他线程都在barrier1等待,有没有办法让等待线程运行到barrier2 ??将barrier.await()方法放在finally块中是不是更好?
发布于 2015-05-28 16:47:19
您正在使用计数器3创建循环屏障。其中两个线程能够调用barrier1.await();,因此等待计数器为零,以便它们可以继续执行,但第三个线程无法调用barrier1.await(),因为您在调用barrier.await()之前显式抛出了异常。因此,计数器将不会为零,并且所有其他线程都将停滞在barrier1.await()。
如果您想让所有其他线程继续执行,则在抛出异常之前,您必须在此块中的某个位置再次调用barrier.await()。
if(Thread.currentThread().getName().equalsIgnoreCase("Car")){
barrier1.await(); // call here
throw new RuntimeException("something weird happened");
}发布于 2017-06-04 21:54:32
理想情况下,您应该使用await的超时版本。如果其中一个线程被阻塞了很长一段时间,那么所有的障碍都有机会退出。
try {
leader = barrier.await(10, TimeUnit.MILLISECONDS); // waits for 10 millis - throws exception if timed out or throws BarrierBrokenExcepion if Barrier is Broker
} catch (TimeoutException e) {
if (barrier.isBroken()) { //on timeout checks if barrier is broken and exits
System.out.println("BARRIER is broken "+Thread.currentThread().getName());
break;
}
} catch (BrokenBarrierException e){
e.printStackTrace();
break;
}您还可以在未命中屏障/抛出异常的线程上调用reset()。这将导致其他两个挂起线程上的BarrierBrokenException。其余的是实现细节。
发布于 2018-04-12 15:09:57
您应该使用Latch或Semaphore而不是Barrier。Simply Barrier用于同步多线程,Latch用于同步事件。
https://stackoverflow.com/questions/30476807
复制相似问题