相关疑难解决方法(0)

易失性保证和无序执行

重要编辑我知道在发生两个赋值的线程中 "发生在之前" 我的问题是,另一个线程是否可能读取"b"非空,而"a"仍为空.所以我知道如果你从与之前调用setBothNonNull(...)的线程相同的线程调用doIt(),那么它就不能抛出NullPointerException.但是如果一个人从另一个线程调用doIt()不是调用setBothNonNull(...)的那个呢?

请注意,这个问题仅仅是对volatile关键字和volatile保证:这是不是synchronized关键字(所以请不要回答"您必须使用同步"因为我没有任何问题要解决:我只是想了解volatile担保关于无序执行(或缺乏保证).

假设我们有一个包含两个volatileString引用的对象,它们被构造函数初始化为null,并且我们只有一种方法来修改两个String:通过调用setBoth(...)并且我们之后只能将它们的引用设置为非null引用(只允许构造函数将它们设置为null).

例如(这只是一个例子,毫无疑问):

public class SO {

    private volatile String a;
    private volatile String b;

    public SO() {
        a = null;
        b = null;
    }

    public void setBothNonNull( @NotNull final String one, @NotNull final String two ) {
        a = one;
        b = two;
    }

    public String getA() …
Run Code Online (Sandbox Code Playgroud)

java volatile java-memory-model

41
推荐指数
2
解决办法
9239
查看次数

Java volatile是否会阻止缓存或强制执行直写缓存?

我正在尝试理解Java的volatile关键字,以便在具有CPU缓存的多线程程序中写入易失性原子变量.

我已经阅读了几个教程和Java语言规范,特别是关于"在订购之前发生"的第17.4.5节.我的理解是,当线程将新值写入volatile变量时,更新的值必须对读取该变量的其他线程可见.对我来说,这些语义可以通过以下两种方式之一实现:

  1. 线程可以在CPU缓存中缓存volatile变量,但是必须立即将对缓存中的变量的写入刷新到主存储器.换句话说,缓存是直写的.

  2. 线程永远不能缓存volatile变量,必须在主内存中读写这些变量.

教程(http://tutorials.jenkov.com)中提到的方法1 说:

通过声明计数器变量volatile,对计数器变量的所有写操作都将立即写回主存储器.

方法2在Stackoverflow问题" Java中的易失性变量 "中提到,本教程还提到:

这个变量的值永远不会被线程本地缓存:所有读写都将直接进入"主存"

哪一个是Java中使用的正确方法?

相关的Stackoverflow问题没有回答我的问题:

Java中的易失性变量

Java volatile是否读取刷新写入,并执行易失性写入更新读取

Java易失性和缓存一致性

java concurrency multithreading caching volatile

10
推荐指数
2
解决办法
2678
查看次数