Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 廉价读写锁中的冗余易失性?_Java_Multithreading_Concurrency_Volatile - Fatal编程技术网

Java 廉价读写锁中的冗余易失性?

Java 廉价读写锁中的冗余易失性?,java,multithreading,concurrency,volatile,Java,Multithreading,Concurrency,Volatile,Brian Goetz在他的文章中 使用下面粘贴的示例作为廉价的读写锁。我的问题是,如果int变量值没有声明为volatile,那么它会有区别吗?我的理解是,由于对值的写入是在同步块内完成的,所以最新的值将以任何方式对其他线程可见,因此声明它为volatile是多余的。请澄清 @ThreadSafe public class CheesyCounter { // Employs the cheap read-write lock trick // All mutative operations

Brian Goetz在他的文章中

使用下面粘贴的示例作为廉价的读写锁。我的问题是,如果int变量值没有声明为volatile,那么它会有区别吗?我的理解是,由于对值的写入是在同步块内完成的,所以最新的值将以任何方式对其他线程可见,因此声明它为volatile是多余的。请澄清

@ThreadSafe
public class CheesyCounter {
// Employs the cheap read-write lock trick
// All mutative operations MUST be done with the 'this' lock held
@GuardedBy("this") private volatile int value;

public int getValue() { return value; }

public synchronized int increment() {
    return value++;
}
}

如果两个或多个线程试图同时递增,则此
已同步
可防止您跳过递增(因为
++
不是原子的)

这可以防止您在一个线程中看到过时的值,而该值在另一个线程中已经递增。(请注意,我们还可以使getValue同步以实现这一点)

我的理解是,由于对值的写入是在同步块内完成的,所以最新的值将以任何方式对其他线程可见

这是不正确的。通常,不能保证其他线程在变量发生更改后立即“看到”更改。线程可能会看到已更改变量的过时值,因为,例如,线程在寄存器而不是主内存中看到该值

一个
volatile
变量建立了“before”语义。报告指出:

两个动作可以由“发生在之前”关系排序。如果一个动作发生在另一个动作之前,那么第一个动作对第二个动作可见并在第二个动作之前排序

  • 易失性
    字段(§8.3.1.4)的写入发生在该字段的每次后续读取之前
委员会:

字段可以声明为volatile,在这种情况下,Java内存模型确保所有线程都能看到变量的一致值(§17.4)


该字段必须是volatile的原因是,即使读取是原子的,它也需要确保该值是当前值,即之前由另一个线程写入的任何值都是可见的。读原子是不够的<代码>易失性
仍然是确保值一致性所必需的。

非常感谢各位的回答。现在在oracle网站上也发现了这一点:“第二,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立“发生在之前”关系。”

getValue
未同步。
getValue()
可能会返回过时的值,因为它未同步,因此
increment()
getValue()
之间没有不带
volatile
public synchronized int increment()
private volatile int value