2015-05-27 2 views
1

я столкнулся вопрос с циклическом барьером, пожалуйста, смотрите в приведенной ниже код -Циклическая Барьер Обработка исключений

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 есть ли способ для запуска ожидающих потоков до сих барьером2 ?? Это лучшая идея поместить метод барьер.await() внутри блока finally?

ответ

1

Вы создаете циклический барьер с счетчиком 3. Два потока могли вызвать барьер1.await(); и, следовательно, ожидание того, что счетчик будет равен нулю, чтобы они могли продолжить дальше, но третий поток не может вызвать барьер1.await(), потому что вы явно бросаете исключение, прежде чем он может вызвать барьер.await(). Следовательно, счетчик не будет равен нулю, и вся другая нить застрянет у барьера1.await().

Если вы хотите, чтобы все остальные потоки продолжались дальше, вы должны снова вызвать барьер.await() еще где-нибудь в этом блоке, прежде чем выбрасывать исключение.

if(Thread.currentThread().getName().equalsIgnoreCase("Car")){ 
       barrier1.await(); // call here 
       throw new RuntimeException("something weird happened"); 
    } 
+0

Здесь я явно бросаю исключение, но что, если какой-то код вызывает исключение из-за какого-то странного состояния. –

+0

Вот что я сказал .. программисту, которому вы должны знать обо всех этих фактах, о том, как работают методы bar.awaits(). Вы должны убедиться, что если есть возможность выбросить исключение, так что инструкция барьер1.await() пропускает то, как вы собираетесь обращаться. Я думаю, что использование надлежащего механизма обработки исключений и знание обстоятельств заранее могут только помочь вам. Удачи. –

+0

Лучше ли вы поместить вызов wait() в блок finally? потому что возможно, что у нас есть несколько ожидающих вызовов. –

0

В идеале вы должны использовать версию ожидания ожидания. Если один из потоков заблокирован в течение очень долгого времени; то это дает шанс на все препятствия для выхода.

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 на двух других висячих потоках. Остальное - детали реализации.

Смежные вопросы