为什么 Spring 框架更喜欢 mutex 而不是 volatile?
Why Spring framework preferes mutex over volatile?
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 并没有带来什么新东西,除了我们有更多的代码行。此外,我们可以在同步块中更改多个变量,但这不是示例中的问题 - 只有一个变量被更改。
P.S。我知道什么是 mutex 和 volatile,请避免在答案中解释 JMM。
没有真正的原因,所以可能只是一个惯例(个人或项目的),但它们是 AtomicBooleans
版本 4.1.6。
active
值是正常使用的(get/set
),但是有一个closed
使用了compareAndSet
.
volatile
与 synchronized
不同。 volatile
只关心线程间数据的可读性。 syncronized
在这种情况下也会阻止并发访问。
此外 before JDK 1.5 volatile
关键字的 use/implementation 未完全或正确实现,因此更安全地使用互斥体,尤其是在 Spring 中的代码中自开始或 JDK 1.5 之前。对于需要支持 Java <= JDK 1.5.
的旧版本框架中的代码,这仍然适用
在 JDK 1.5 或更高版本可用的框架的较新部分中,您会看到更多地使用 volatile
或 Atomic*
类。在仅支持 JDK 1.6 及更高版本的较新版本中,已完成大量清理工作。
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 并没有带来什么新东西,除了我们有更多的代码行。此外,我们可以在同步块中更改多个变量,但这不是示例中的问题 - 只有一个变量被更改。
P.S。我知道什么是 mutex 和 volatile,请避免在答案中解释 JMM。
没有真正的原因,所以可能只是一个惯例(个人或项目的),但它们是 AtomicBooleans
版本 4.1.6。
active
值是正常使用的(get/set
),但是有一个closed
使用了compareAndSet
.
volatile
与 synchronized
不同。 volatile
只关心线程间数据的可读性。 syncronized
在这种情况下也会阻止并发访问。
此外 before JDK 1.5 volatile
关键字的 use/implementation 未完全或正确实现,因此更安全地使用互斥体,尤其是在 Spring 中的代码中自开始或 JDK 1.5 之前。对于需要支持 Java <= JDK 1.5.
在 JDK 1.5 或更高版本可用的框架的较新部分中,您会看到更多地使用 volatile
或 Atomic*
类。在仅支持 JDK 1.6 及更高版本的较新版本中,已完成大量清理工作。