gpt4 book ai didi

java - 处理与循环障碍相关的异常的更好方法

转载 作者:行者123 更新时间:2023-11-30 07:58:41 25 4
gpt4 key购买 nike

我正在尝试将一些业务案例映射到循环障碍的使用。假设我们正在进行促销优惠,但只有 3 位客户可以获得促销优惠。其余的将无法获得此优惠。

为了绘制这个场景,我使用了循环屏障。尽管代码有效,但我不确定如何处理某些客户无法获得报价的情况。现在,我尝试使用带有超时值的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 获得促销优惠!
  • 主题 1 获得促销优惠!
  • 主题 5 获得促销优惠!
  • 由于超时异常,线程 3 无法获取促销优惠
  • 由于屏障异常,线程 4 无法获得促销优惠

最佳答案

仅当 3 位客户尝试访问优惠时,CyclicBarrier 才会触发。

因此,如果只有 1 个客户尝试访问它,它将被阻止,直到另外 2 个客户也尝试访问它!一旦屏障跳闸,它就会被简单地重置,并且该机制就会重新开始。您可以观察是否创建 6 个以上线程而不是 5 个。

所以 CyclicBarrier 似乎不是您正在寻找的东西。

您可能想要计算已访问该优惠的客户数量并拒绝新客户:

private static class PromotionBarrier {
private final AtomicBoolean hasAccess = new AtomicBoolean(false);
private final AtomicLong counter = new AtomicLong(0);
private final long maxCustomers = 3;
public boolean hasAccess() {
if(hasAccess.get()) {
long value = counter.incrementAndGet();
if(value <= maxCustomers) {
return true;
} else {
hasAccess.set(false);
return false;
}
}
return false;
}
}

private static class PromotionRunnable implements Runnable {
private final PromotionBarrier promotionBarrier;

public PromotionRunnable(final PromotionBarrier promotionBarrier) {
this.promotionBarrier = barrier;
}

@Override
public void run() {
if(promotionBarrier.hasAccess()) {
// Yoohoo I got it!
} else {
// Rha I am too late!!
}
}

关于java - 处理与循环障碍相关的异常的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32251462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com