Tag: java memory model

双重检查锁定没有波动

我读到了关于如何进行双重检查锁定的问题: // Double-check idiom for lazy initialization of instance fields private volatile FieldType field; FieldType getField() { FieldType result = field; if (result == null) { // First check (no locking) synchronized(this) { result = field; if (result == null) // Second check (with locking) field = result = computeFieldValue(); } } return result; } […]

有效不可变对象

我想确保根据Java Memory Model正确理解’Effectively Immutable Objects’行为。 假设我们有一个可变类,我们希望将其发布为有效的不可变类: class Outworld { // This MAY be accessed by multiple threads public static volatile MutableLong published; } // This class is mutable class MutableLong { private long value; public MutableLong(long value) { this.value = value; } public void increment() { value++; } public long get() { return value; } […]

JIT可以在某些表达式中将两个易失性读取合并为一个吗?

假设我们有一个volatile int a 。 一个线程呢 while (true) { a = 1; a = 0; } 而另一个线程呢 while (true) { System.out.println(a+a); } 现在,JIT编译器发出对应于2*a而不是a+a汇编是不合法 a+a吗? 一方面,易失性读取的目的是它应该始终从内存中消失。 另一方面,两个读取之间没有同步点,所以我看不出primefaces地处理a+a是违法的,在这种情况下我看不出像2*a这样的优化会如何破坏规范。 参考JLS将不胜感激。

JVM是否保证缓存不是volatile变量?

JVM是否保证缓存不是volatile变量? 程序员是否可以依赖JVM来始终为每个线程本地缓存非易失性变量。 或者JVM可能会也可能不会这样做,因此程序员不应该依赖于JVM。 感谢您提前的答案。

具有非final字段的不可变对象如何是线程不安全的?

说我们有这个 // This is trivially immutable. public class Foo { private String bar; public Foo(String bar) { this.bar = bar; } public String getBar() { return bar; } } 是什么让这个线程不安全? 继这个问题之后 。

为什么在CopyOnWriteArrayList中需要setArray()方法调用

在CopyOnWriteArrayList.java中,在方法集(int index,E element)下面 public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); Object oldValue = elements[index]; if (oldValue != element) { int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write […]

解释Java并发中的“程序顺序规则”

程序顺序规则指出“线程中的每个操作都发生在 – 该程序顺序中稍后出现的该线程中的每个操作之前” 我在另一个线程中读到了一个动作 读取和写入变量 锁定和解锁显示器 开始和加入线程 这是否意味着可以按顺序更改读取和写入,但读取和写入不能使用第2行或第3行中指定的操作更改顺序? 2.“程序顺序”是什么意思? 对示例的解释将非常有用。 其他相关问题 假设我有以下代码: long tick = System.nanoTime(); //Line1: Note the time //Block1: some code whose time I wish to measure goes here long tock = System.nanoTime(); //Line2: Note the time 首先,它是一个单线程应用程序,以保持简单。 编译器注意到它需要检查两次时间并且还注意到与周围时间注释行没有依赖关系的代码块,因此它看到了重组代码的可能性,这可能导致Block1不被定时调用包围在实际执行期间(例如,考虑此顺序Line1-> Line2-> Block1)。 但是,作为程序员,我可以看到Line1,2和Block1之间的依赖关系。 Line1应该紧接在Block1之前,Block1需要有限的时间才能完成,并且Line2立即成功。 所以我的问题是:我是否正确测量了块? 如果是,那么是什么阻止了编译器重新排列顺序。 如果不是,(通过Enno的答案后认为是正确的)我该怎么做才能防止它。 PS:我最近在SO中提出的另一个问题偷了这个代码。

请解释Java内存模型中详述的初始化安全性

有人可以解释Java内存模型所要求的初始化安全性吗? 最终字段如何帮助实现初始化安全性 ? 构造函数在确保初始化安全性方面起什么作用?

是否保证在另一个线程中看到一个线程中非易失性成员变量的赋值?

考虑下面的Java示例。 请注意,两个类成员变量都没有声明为volatile 。 如果我正在理解内存模型并且“之前发生”规则正确,Java实现可以优化run()方法,以便它永远运行,即使另一个线程调用stopNow()方法。 这可能发生,因为run()方法中没有任何内容强制线程多次读取stop的值。 那是对的吗? 如果没有,为什么不呢? class Example implements Runnable { boolean stop = false; int value = 0; public void stopNow() { stop = true; } public int getValue() { return value; } @Override public void run() { // Loop until stop is set to true. while (!stop) { ++value; } return; } […]

理解发生在之前和同步

我试图理解Java 发生 – 在订单概念之前 ,有一些事情看起来很混乱。 据我所知,之前发生的只是行动集上的一个订单,并没有提供有关实时执行订单的任何保证。 实际上(强调我的): 应该注意的是,两个动作之间存在的先发生关系并不一定意味着它们必须在实现中以该顺序发生。 如果重新排序产生的 结果与合法执行一致,则不是非法的。 所以,它说的是,如果有两个动作w (写入)和r (读取)使得hb(w,r) ,而不是r 可能实际上在执行之前发生,但是不能保证它会。 读取r也观察到写入w 。 我如何确定在运行时随后执行两个操作? 例如: public volatile int v; public int c; 操作: Thread A v = 3; //w Thread B c = v; //r 这里我们有hb(w, r)但这并不意味着c在赋值后将包含值3 。 如何强制执行c分配3? 同步订单是否提供此类保证?