【问题标题】:Why Spring framework preferes mutex over volatile?为什么 Spring 框架更喜欢 mutex 而不是 volatile?
【发布时间】:2015-07-02 11:15:21
【问题描述】:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext, DisposableBean {

   private boolean active = false;
   private final Object activeMonitor = new Object();

   public boolean isActive() {
      synchronized (this.activeMonitor) {
         return this.active;
      }
   }

   protected void cancelRefresh(BeansException ex) {
       synchronized (this.activeMonitor) {
          this.active = false;
       }
   }

   ...
}

为了读取一致性,使用 mutex 而不是 volatile 有什么必要的,还是只是偏好/代码约定/等的问题?乍一看,mutex 并没有什么新东西,只是我们有更多的代码行。此外,我们可以在同步块中更改多个变量,但这不是示例中的问题 - 仅更改了一个变量。

附:我知道什么是互斥体和易失性,请避免在答案中解释 JMM。

【问题讨论】:

    标签: java spring concurrency mutex volatile


    【解决方案1】:

    volatilesynchronized 不同。 volatile 只负责线程间数据的可读性。 syncronized 在这种情况下也会阻止并发访问。

    另外before JDK 1.5 volatile 关键字的使用/实现没有完全或正确实现,因此互斥锁的使用更安全,特别是在 Spring 自开始或 JDK 1.5 之前的代码中。对于需要支持 Java

    在可供 JDK 1.5 或更高版本使用的框架的较新部分中,您会看到更多地使用 volatileAtomic* 类。在仅支持 JDK 1.6 及更高版本的较新版本中,已经完成了大量清理工作。

    【讨论】:

    • 但是 java 1.5 是在 2004 年发布的,spring 3.2 是在 2013 年左右发布的。所以重构它花了大约 10 年?
    • Spring 3.x 是用于在 spring 中升级 API 而不是实际的内部结构,为什么要修复一些没有损坏的东西。但事实是该代码源自 Spring 的早期版本,因此没有原子或适当的 volatile。
    • 所以,底线:spring 使用互斥锁,因为它是过去的遗产。
    • 是的。在 4.x 行中,对此进行了一些清理。
    【解决方案2】:

    没有真正的原因,所以可能只是一个约定(个人或项目的),但它们在 4.1.6 版本中是 AtomicBooleans

    active 值正常使用 (get/set),但有一个 closed 使用 compareAndSet

    【讨论】:

      猜你喜欢
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      相关资源
      最近更新 更多