我正在尝试将一些商业案例映射到循环障碍的使用。假设我们正在进行促销优惠,只有 3 位客户可以获得促销优惠。其余的将无法获得报价。
为了映射这个场景,我使用了 Cyclic Barrier。即使代码正常工作,我也不确定如何处理某些客户无法获得报价的情况。现在,我尝试使用具有超时值的 await() API,以便我可以捕获TimeoutException并让客户知道他无法使用促销优惠。这导致了另一个等待线程的BarrierBrokenException 。
我想知道,我们如何才能优雅地处理这些场景,以便选定的客户获得促销优惠,而那些无法遵循不同代码路径的客户。
我的代码 -
public class CyclicBarrierExample {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
Thread[] threads = new Thread[5];
CyclicBarrier barrier = new CyclicBarrier(3, ()->{System.out.println("Barrier limit of 3 reached. 3 threads will get the promotional offer!");});
Runnable nr = new PromotionRunnable(barrier);
int i = 0;
for (Thread t : threads) {
t = new Thread(nr, "Thread " + ++i);
t.start();
}
System.out.println("main thread has completed");
}
private static class PromotionRunnable implements Runnable {
private final CyclicBarrier barrier;
public PromotionRunnable(final CyclicBarrier barrier) {
this.barrier = barrier;
}
/*
* As per the doc, BrokenBarrierException is thrown when another thread timed out while the current thread was waiting.
* This explains why we are able to see both Timeout and Broken Barrier Exceptions.
*/
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " trying to get the promotional offer!");
try {
barrier.await(2000L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
return;
} catch (BrokenBarrierException e) {
System.out.println(Thread.currentThread().getName() + " could not get the promotional offer, due to barrier exception");
return;
} catch (TimeoutException e) {
System.out.println(Thread.currentThread().getName() + " could not get the promotional offer, due to timeout exception");
return;
}
System.out.println(Thread.currentThread().getName() + " got the promotional offer!");
}
}
}
其中一次运行的输出 -
- 线程 1 试图获得促销优惠!
- 线程 4 试图获得促销优惠!
- 主线程已完成
- 线程 3 试图获得促销优惠!
- 线程 2 试图获得促销优惠!
- 线程 5 试图获得促销优惠!
- 障碍达到前三名,他们将获得促销优惠!
- 线程 2 获得促销优惠!
- Thread 1 收到促销优惠!
- Thread 5 收到促销优惠!
- 由于超时异常,线程 3 无法获得促销优惠
- 由于屏障异常,线程 4 无法获得促销优惠