首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环屏障异常处理

循环屏障异常处理
EN

Stack Overflow用户
提问于 2015-05-27 16:16:08
回答 3查看 1.3K关注 0票数 1

我正面临一个循环障碍的问题,请查看下面的代码-

MeetingPoint1.java

代码语言:javascript
复制
public class MeetingPoint1 implements Runnable{

    @Override
    public void run() {
        System.out.println(" MeetingPoint1 one cleared... ");
    }

}

MeetingPoint2.java

代码语言:javascript
复制
public class MeetingPoint2 implements Runnable{

    @Override
    public void run() {
        System.out.println(" MeetingPoint Two cleared... ");
    }

}

VehicalRunnable.java

代码语言:javascript
复制
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

代码语言:javascript
复制
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块中是不是更好?

EN

回答 3

Stack Overflow用户

发布于 2015-05-28 16:47:19

您正在使用计数器3创建循环屏障。其中两个线程能够调用barrier1.await();,因此等待计数器为零,以便它们可以继续执行,但第三个线程无法调用barrier1.await(),因为您在调用barrier.await()之前显式抛出了异常。因此,计数器将不会为零,并且所有其他线程都将停滞在barrier1.await()。

如果您想让所有其他线程继续执行,则在抛出异常之前,您必须在此块中的某个位置再次调用barrier.await()。

代码语言:javascript
复制
 if(Thread.currentThread().getName().equalsIgnoreCase("Car")){
                barrier1.await(); // call here
                throw new RuntimeException("something weird happened");
   }
票数 1
EN

Stack Overflow用户

发布于 2017-06-04 21:54:32

理想情况下,您应该使用await的超时版本。如果其中一个线程被阻塞了很长一段时间,那么所有的障碍都有机会退出。

代码语言:javascript
复制
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。其余的是实现细节。

票数 0
EN

Stack Overflow用户

发布于 2018-04-12 15:09:57

您应该使用Latch或Semaphore而不是Barrier。Simply Barrier用于同步多线程,Latch用于同步事件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30476807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档