【问题标题】:Thread safe circuit breaker线程安全断路器
【发布时间】:2012-11-06 15:17:18
【问题描述】:

我正在尝试将断路器模式作为一种学习体验来实现(我知道这种模式已经在多个框架中实现了)。

我的幼稚、简化且非线程安全的实现看起来像

CircuitBreaker circuitBreaker = null;
    try {
        //get the current circuit breaker
        if (circuitBreaker.isOpen()) {
             throw new CircuitBreakerOpenException();
        } else {
             //proceed normally
             //or retry if half open
        }
    } catch (CircuitBreakerCallbackExecutionException e) {
        //update or replace the circuit breaker
    }

如何在不同步受保护调用(断路器对象)的情况下实现线程安全?理想情况下,如果失败阈值设置为 10,我不希望在远程系统出现故障时允许超过 10 个多线程调用通过警卫。

到目前为止,我还没有找到任何看起来 100% 线程安全的开源框架。但也许试图实现这一目标是没有意义的。

这个问题更多是关于线程安全而不是断路器。

【问题讨论】:

  • 只是为了澄清:我知道为什么这不是线程安全的。但我不知道如何让它线程安全。
  • 我不太明白这个问题,或者我看错了,你是说你永远不想超过 10 个通话在任何时候都处于活动状态?否则,如果在系统失败之前有 100 个调用通过了断路器,那么您将有 100 个活动调用仍然“在”受断路器保护的代码“内部”,您说最多需要 10 个。
  • 可以说远程系统已启动并且一切正常。但在某些时候,对远程系统的所有调用都会超时。我想要的是限制那些得到例如 TimedOutException 的调用不超过 10。
  • 我可以通过在断路器上进行同步来实现这一点,但这会大大降低系统的吞吐量。
  • 断路器可以设置为wait-free(使用AtomicInteger 可能是一个好的开始),但我想不出任何方法可以在不引入单个锁定/等待的情况下将其与节流结合起来.

标签: java multithreading thread-safety locking


【解决方案1】:

如果我理解正确的话,isOpen 方法访问一个共享变量,大概是一个boolean。您需要做的就是将该布尔值设为volatile。这将确保健康检查线程对其的任何写入对所有资源获取线程都是立即可见的。

【讨论】:

  • 你理解正确!但是我正在做类似 if (condition) do something => 比赛条件
  • 我看不到比赛条件。您必须提供更多细节才能使其变得明显。请注意,当您“做某事”时,不需要保持条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
相关资源
最近更新 更多