繁体   English   中英

混淆 java 线程变量可见性

[英]confuse about java thread variable visibility

我发现的所有关于可见性的例子都是原始类型的例子。 我想知道的是:如果一个 object 在堆中是新的,当一个线程调用它的方法来改变它的 state 时,没有锁定或同步,其他线程会看到这个变化吗? 想象一个Java.Collection object,一个线程调用它的add()方法

Someone says for object in heap still has visibility problem, but the JLS said: 17.4.1 Shared Variables Memory that can be shared between threads is called shared memory or heap memory.

and http://www.artima.com/insidejvm/ed2/jvm2.html said: A thread's Java stack stores the state of Java (not native) method invocations for the thread. Java 方法调用的 state 包括其局部变量、调用它的参数、其返回值(如果有)和中间计算。

所以我认为, JVM 不会将堆中的 object 复制到 CPU 缓存中。 如果这是正确的,堆中的 object 不会有可见性问题,因为线程只是引用堆中的 object。

顺便说一句,假设一个线程调用.add() 时存在并发问题。 在正常的过程中,更改必须带有锁,所以这个问题不是问题。 但我只想知道:)

答案是“不,其他线程不一定会看到对集合的更改”,因为(大部分)标准 Collections 不是线程安全的 - 也就是说,他们没有安全发布其 state。 (另一个线程可能会,也可能不会看到变化)。

That is why the java.util.concurrent package was created - it provides thread-safe implementations of java.util.Collections.

如果您有volatile 、 atomic 变量或其他提供happens-before语义的并发容器,您仍然可以在没有synchronized的情况下执行 memory 同步。 但是,如果您不执行任何这些操作,那么 memory 可见性就无法保证。

在您的特定情况下,如果您想在一个线程中的容器上调用add()并使其在另一个线程中可见而无需显式锁定,那么这仅在容器是并发容器时才有效(例如,在java.util.concurrent包)或同步包(例如Collections.synchronizedList )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM