相关疑难解决方法(0)

Java重新排序会影响System.currentTimeMillis()吗?

根据Java Memory Model,只要执行结构良好,指令就可以重新排序.

所以我想知道,以下代码是否可能产生以下输出?

[代码] [在同一个主题中]

long a = System.currentTimeMillis();
long b = System.currentTimeMillis();
long c = System.currentTimeMillis();
Run Code Online (Sandbox Code Playgroud)

[输出]

a == 10, b == 20, c == 15
Run Code Online (Sandbox Code Playgroud)

如果不可能,那么JVM /实现会做些什么来防止这种情况发生?

java java-memory-model order-of-execution

18
推荐指数
1
解决办法
512
查看次数

如何理解发生 - 在一致之前

JLS的第17章中,它引入了一个概念:发生在一致之前.

如果对于A中的所有读取r,其中W(r)是r看到的写入动作,那么一组动作A发生 - 在一致之前,不是hb(r,W(r))或那里的情况在A中存在写w,使得wv = rv和hb(W(r),w)和hb(w,r)"

在我的理解中,它等于以下几个词:...,既不是......也不是......

所以我的前两个问题是:

  • 我的理解对吗?
  • "wv = rv"是什么意思?

它还给出了一个例子:17.4.5-1

Thread 1 Thread 2

B = 1; A = 2; 

r2 = A; r1 = B; 
Run Code Online (Sandbox Code Playgroud)

在第一个执行顺序中:

1: B = 1;

3: A = 2;

2: r2 = A;  // sees initial write of 0

4: r1 = B;  // sees initial write of 0
Run Code Online (Sandbox Code Playgroud)

订单本身已经告诉我们两个线程交替执行,所以我的第三个问题是:左数是什么意思?

在我的理解中,r2和r1的原因可以看出0的初始写入是A和B都不是volatile字段.所以我的第四个问题是:我的理解是否正确?

在第二个执行顺序中:

1: r2 = A;  // sees write of A = 2

3: r1 = B;  // sees …
Run Code Online (Sandbox Code Playgroud)

java memory-model

11
推荐指数
2
解决办法
4350
查看次数

设置HashMap线程安全吗?

HashMap我的程序中有一个由多个线程访问,偶尔由一个线程设置.

例如:

Map<String, String> myMap = new HashMap<String, String>();
Run Code Online (Sandbox Code Playgroud)

这可以通过多个线程访问.每小时一次,一个线程调用:

myMap = myRefreshedVersionOfTheMap;
Run Code Online (Sandbox Code Playgroud)

所以我的问题是这是否是线程安全的.如果两个映射始终都有密钥"importantKey",那么读取线程是否可以在"importantKey"不存在时访问映射?

编辑:

感谢答案,我意识到这个问题实际上是独立的HashMap.这是一个关于对象引用分配的问题.

java multithreading reference thread-safety java-memory-model

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

我是否有重新排序问题,是否因为参考逃脱?

我有这个类,我在那里使用它们来缓存实例并克隆它们(数据是可变的).

我想知道我是否可以面对这个重新排序的问题.

我已经看过这个答案和JLS,但我仍然没有信心.

public class DataWrapper {
    private static final ConcurrentMap<String, DataWrapper> map = new ConcurrentHashMap<>();
    private Data data;
    private String name;

    public static DataWrapper getInstance(String name) {
        DataWrapper instance = map.get(name);
        if (instance == null) {
            instance = new DataWrapper(name);
        }
        return instance.cloneInstance();
    }

    private DataWrapper(String name) {
        this.name = name;
        this.data = loadData(name);  // A heavy method
        map.put(name, this);  // I know
    }

    private DataWrapper cloneInstance() {
        return new DataWrapper(this);
    }

    private DataWrapper(DataWrapper that) {
        this.name …
Run Code Online (Sandbox Code Playgroud)

java multithreading java-memory-model happens-before

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

“同步操作完全有序”是什么意思?

我正在阅读《Java并发实践》,在“16.1.3 500字以内的Java内存模型”中,它说:

\n\n
\n

Java 内存模型是根据操作来指定的,包括对变量的读取和写入、监视器的锁定和解锁以及线程的启动和加入。JMM为程序中的所有操作定义了一个名为“happens-before”的部分排序。为了保证执行动作B的线程可以看到动作A的结果(无论A和B是否发生在不同的线程中),A和B之间必须存在happens-before关系。在没有happens-before排序的情况下在两个操作之间,JVM 可以随意对它们重新排序。

\n\n

尽管动作只是部分有序的,但同步动作\xe2\x80\x94锁的获取和释放以及易失性变量\xe2\x80\x94的读写都是完全有序的这使得根据 \xe2\x80\x9csubsequent\xe2\x80\x9d 锁定获取和易失性变量的读取来描述发生之前是有意义的。

\n
\n\n

关于“部分排序”,我找到了这个这个,但我不太明白“即使动作只是部分排序,同步动作\xe2\x80\x94锁获取和释放,以及易失性变量的读写\ xe2\x80\x94 是完全有序的。” “同步操作完全有序”是什么意思?

\n

java multithreading happens-before

5
推荐指数
1
解决办法
547
查看次数

Java 发生在关系之前?

考虑以下代码。

public class Test {
    private boolean running = false;

    public void run() {
        running = true;
    }

    public void test() {
        boolean running1 = running;
        boolean running2 = running;
        System.out.println("running1: " + running1);
        System.out.println("running2: " + running2);
    }
}
Run Code Online (Sandbox Code Playgroud)

线程 A 调用run(),然后另一个线程 B 调用test()并且不应该有任何发生之前的关系。我知道不能保证线程 B 看到线程 A 所做的更改。但是这个程序的输出有没有可能是:

running1: true
running2: false
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading thread-safety happens-before

1
推荐指数
1
解决办法
65
查看次数