Tag: 性volatile

在Java中对volatile对象进行非易失性引用的行为

来自C / C ++,我对Java中的volatile对象行为有点困惑。 我知道Java中的volatile有两个属性: 不会将对象带入缓存,始终将其保存在主内存中。 保证“发生在之前” 但是我不确定如果我对对象进行新的非易失性引用会发生什么。 例如, class Example { private volatile Book b = null; public init() { b = new Book(…); } public use() { Book local = b; local.read(); } } AFAIK,volatile表示b引用的“book对象”应该在主内存中。 编译器可能在内部实现引用作为指针,因此b指针可能位于缓存中。 根据我的理解,volatile是对象的限定符,而不是引用/指针。 问题是:在use方法中,本地引用不是volatile。 这个“本地”引用是否会将基础Book对象从主内存带入缓存,从根本上使对象不“易变”?

易失性变量和非易失性重新排序/可见性

所以我认为我已经足够了解这些东西,直到我读到让我怀疑这个主题的东西。 我几乎可以肯定这本书是不正确的,但也想问社区。 PS:没有看过这本书的勘误,所以很可能被误认为是错误的。 一个简化的例子: public class VolatileMain { private volatile int a = 0; private String text = “”; public static void main(String[] args) throws Exception { VolatileMain vm = new VolatileMain(); Thread writer = new Thread() { @Override public void run() { System.out.println(“Running thread ” + Thread.currentThread().getName()); vm.text = “hello world”; vm.a = 5; […]

我也需要volatile参考类型的变量吗?

我们经常使用volatile来确保每个Thread都可以看到条件变量。 到目前为止,我看到volatile字段在代码中都是primitive type 。 object字段有这个问题吗? 例如: class a { public String str; public List list; } 如果有一些线程将访问str和list,我必须添加’volatile’吗? 我想每次访问Object都会直接从Heap获取,并且Object不会像原始类型那样被缓存。 是对的吗?

参考类型的易失性 – 是否总是避免因JMM而导致出现参考问题?

假设这堂课: public class AmIThreadSafe { private int a; private int b; AmIThreadSafe(int a, int b) { this.a = a; this.b = b; } } 假设实例对此类的引用(声明为volatile )可以被一些线程访问(导致竞争条件),只要this (引用)转义: volatile AmIThreadSafe instance = new AmIThreadSafe(1,2); 在这里,我确信分配instance引用的事实发生在线程读取之前 。 但AmIThreadSafe’s领域呢? 外部volatile关键字是否也意味着关于a和b字段happens-before关系? 或者由于在构造函数中重新排序的潜在语句,是否有可能最终得到任何线程看到过时的值(在这种情况下,因为int默认值为0 )? 换句话说,我应该声明a和b final或volatile来防止JMM出现任何意外,或者只是在实例的引用上指示volatile吗? —————- 更新的post – 一个好的答案: ————————— – 下面的文章通过其样本证实,在我的情况下, a和b受到保护,不受JMM优化的影响,这些优化会阻止永久发生之前的关系。 http://jeremymanson.blogspot.fr/2008/11/what-volatile-means-in-java.html

不稳定的出版物保证多深?

众所周知,如果我们有一些对象引用并且此引用具有final字段 – 我们将看到来自final字段的所有可到达字段(至少在构造函数完成时) 例1: class Foo{ private final Map map; Foo(){ map = new HashMap(); map.put(1,”object”); } public void bar(){ System.out.println(map.get(1)); } } 正如我在这种情况下所做的那样,我们保证bar()方法始终输出object因为: 我列出了Foo类的完整代码,地图是最终的; 2.如果某个线程会看到Foo引用和这个引用!= null,那么我们保证从最终的map引用值可以到达的是实际的 。 我也是这么认为的 例2: class Foo { private final Map map; private Map nonFinalMap; Foo() { nonFinalMap = new HashMap(); nonFinalMap.put(2, “ololo”); map = new HashMap(); map.put(1, “object”); } […]