第16章 Java内存模型
什么是内存模型,为什么需要它
aVariable = 3;
内存模型需要解决这个问题:这什么条件下,读取aVariable的线程看到这个值为3
JMM 规定了 JVM 必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对于其他线程可见。 JMM 在设计时就在可预测性和程序的易于开发性之间进行了权衡,从而旨在各种主流的处理器体系架构上能实现高性能的 JVM
平台的内存模型
在共享内存的多处理器体系架构中,每个处理器都拥有自己的缓存,并且定期地与主内存进行协调。在不同的处理器架构中提供了不同级别的缓存一致性(Cache Coherenc的,其中一部分只提供最小的保证,即允许不同的处理器在任意时刻从同一个存储位置上看到不同的值。
重排序
同步将限制编译器、运行时和硬件对内存操作重排序的方式,从而实施重排序时不会破坏 JMM 提供的可见性保证。
Java内存模型简介
JMM 为程序中所有的操作定义了一个偏序关系 ,称之Happens-Before.
- 程序顺序规则
- 监视器锁规则
- volatile 变量规则
- 线程启动规则
- 中断规则
- 终结器规则
- 传递性
借助同步
由于 Happens-Before 的排序功能很强大,因此有时候可以“借助( Piggyback )"现有同步机制的可见性属性。
程序清单 16-2 说明如何借助同步的 FutureTask 的内部类
// FutureTask 内部类
private final class Sync extends AbstractQueuedSynchronizer {
private static final int RUNNING = 1, RAN = 2, CANCELLED = 4;
private V result;
private Exception exception;
void innerSet(V v) {
while (true) {
int s = getState();
if (ranOrCancelled(s)) {
return;
}
if (compareAndSetState(s, RAN)) {
break;
}
}
result = v;
releaseShared(0);
done();
}
V innerGet() throws InterruptedException, ExecutionException {
acquireSharedInterruptibly(0);
if (getState() == CANCELLED) {
throw new CancellationException();
}
if (exception != null) {
throw new ExecutionException(exception);
}
return result;
}
}