Volatile 用于发布有效的不可变对象
Volatile for publishing effectively immutable objects
仅使用 volatile
来发布永不改变的可变对象是否安全?
class Mutable {
private int i;
Mutable(int i) {
this.i=i;
}
int getI() {
return i;
}
}
这个class被多个线程访问:
@Singleton
class Holder {
private volatile Mutable effectivelyImmutable = new Mutable(1);
int getI() {
return effectivelyImmutable.getI();
}
void resetMutalbe(int i) {
Mutable newMutable = new Mutable(i);
effectivelyImmutable = newMutable;
}
}
如果从未调用 Holder.resetMutalbe()
,所有线程是否都会从 Holder.getI()
获取 1?
如果在 Holder.getI()
之前从任何线程调用 Holder.resetMutalbe(2)
,所有线程都会从 Holder.getI()
获得 2 吗?
是的,volatile
就足够了,因为它创建了一个 happens-before 关系。写入 volatile 字段发生在读取之前,因此调用 Holder#resetMutalbe()
之前的所有操作在调用 Holder#getI()
.
之后可见
仅使用 volatile
来发布永不改变的可变对象是否安全?
class Mutable {
private int i;
Mutable(int i) {
this.i=i;
}
int getI() {
return i;
}
}
这个class被多个线程访问:
@Singleton
class Holder {
private volatile Mutable effectivelyImmutable = new Mutable(1);
int getI() {
return effectivelyImmutable.getI();
}
void resetMutalbe(int i) {
Mutable newMutable = new Mutable(i);
effectivelyImmutable = newMutable;
}
}
如果从未调用 Holder.resetMutalbe()
,所有线程是否都会从 Holder.getI()
获取 1?
如果在 Holder.getI()
之前从任何线程调用 Holder.resetMutalbe(2)
,所有线程都会从 Holder.getI()
获得 2 吗?
是的,volatile
就足够了,因为它创建了一个 happens-before 关系。写入 volatile 字段发生在读取之前,因此调用 Holder#resetMutalbe()
之前的所有操作在调用 Holder#getI()
.