标签: java-memory-model

吊装和重新订购同样的东西?

我从Effective Java中读到,在没有同步的情况下,下面的序列A可以被虚拟机转换为序列B并调用它hoisting.我还在某处读到,如果变量未被声明为涉及变量的易失性指令,则可以重新排序.吊装和重新订购同样的东西?

  while (!done)    sequence A     
    i++;

  if (!done)
     while (true)    sequence B
        i++;
Run Code Online (Sandbox Code Playgroud)

java java-memory-model

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

易失性读取是否发生在易失性写入之前?

我试着理解为什么这个例子是一个正确同步的程序:

a - volatile
Thread1:
x=a
Thread2:
a=5
Run Code Online (Sandbox Code Playgroud)

因为存在冲突的访问(存在对a的写入和读取)所以在每个顺序一致性执行中必须发生 - 在该访问之间的关系之前.假设一个顺序执行:

1. x=a
2. a=5
Run Code Online (Sandbox Code Playgroud)

1发生在2之前,为什么?

java multithreading synchronization java-memory-model

12
推荐指数
2
解决办法
1154
查看次数

假设我知道我将在x64 cpu上运行,我可以忽略哪些JVM同步实践?

我知道JVM内存模型是针对CPU的最低公分母而设计的,因此它必须假设JVM可以运行的最弱模型(例如ARM).

现在,考虑到x64具有相当强大的内存模型,假设我知道我的程序只能运行在64位x86 CPU上,我可以忽略哪些同步实践?当我的程序通过虚拟化运行时,这也适用吗?

示例:
众所周知,JVM的内存模型需要同步对long和double的读/写访问,但可以假设其他32位原语(如int,float等)的读/写是原子的.

但是,如果我知道,我是一个64位的x86机器上运行,我可以忽略使用上多头锁/双打知道CPU将原子读/写64个值,只是让他们挥发物(像我会整型/花车)?

java concurrency jvm java-memory-model

12
推荐指数
3
解决办法
464
查看次数

Java内存模型:混合不同步和同步

假设有一个这样的类:

public void MyClass {
    private boolean someoneTouchedMeWhenIWasWorking;

    public void process() {
        someoneTouchedMeWhenIWasWorking = false;
        doStuff();
        synchronized(this) {
            if (someoneTouchedMeWhenIWasWorking) {
                System.out.println("Hey!");
            }
        }
    }

    synchronized public void touch() {
        someoneTouchedMeWhenIWasWorking = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

一个线程调用process,另一个调用touch.注意process启动时如何在没有同步的情况下清除标志.

使用Java内存模型,运行的线程是否有可能process看到其本地,非同步写入的效果,即使touch稍后发生?

也就是说,如果线程按此顺序执行:

T1: someoneTouchedMeWhenIWasWorking = false; // Unsynchronized
T2: someoneTouchedMeWhenIWasWorking = true; // Synchronized
T1: if (someoneTouchedMeWhenIWasWorking) // Synchronized
Run Code Online (Sandbox Code Playgroud)

... T1是否有可能从本地缓存中看到值?它可以首先刷新它对内存的所有内容(覆盖T2编写的内容),并从内存中重新加载该值吗?

是否有必要同步第一次写入或使变量变为volatile?

如果答案得到文档或一些可敬的消息来源的支持,我将非常感激.

java multithreading java-memory-model

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

Java:保证非最终引用字段的正确方法永远不会被读为null?

我正在尝试解决一个简单的问题,并陷入Java内存模型兔子洞.

什么是最简单和/或最有效(判断调用此处),但无竞争(根据JMM精确定义)编写包含非最终引用字段的Java类的方法,该字段初始化为非空值构造函数,后来从未改变过,这样任何其他线程的后续访问都不能看到非空值?

破碎的起始示例:

public class Holder {

  private Object value;

  public Holder(Object value) {
    if (value == null)
        throw NullPointerException();
    this.value = value;
  }

  public Object getValue() {    // this could return null!
    return this.value;
  }
}
Run Code Online (Sandbox Code Playgroud)

而根据这篇文章,标记该领域volatile甚至不起作用!

public class Holder {

  private volatile Object value;

  public Holder(Object value) {
    if (value == null)
        throw NullPointerException();
    this.value = value;
  }

  public Object getValue() {    // this STILL could return null!!
    return this.value;
  }
} …
Run Code Online (Sandbox Code Playgroud)

java java-memory-model

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

有效不可变对象

我想确保根据Java内存模型正确理解'有效不可变对象'的行为.

假设我们有一个可变类,我们希望将其发布为有效的不可变类:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

我们执行以下操作:

// Create a mutable object and modify it
MutableLong val = new MutableLong(1);
val.increment();
val.increment();
// No more modifications
// UPDATED: Let's say for this example we …
Run Code Online (Sandbox Code Playgroud)

java concurrency immutability java-memory-model

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

设置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
查看次数

是否从Java中的引用数组中预取了对象?

想象一下,我们在内存中分散了1000个相同类型的对象(它们是在不同时间创建的,其他对象是在其间创建的).

我们有一个数组,它包含对1000个对象中每个对象的引用.

如果我们按顺序遍历数组,那么将预取到CPU的高速缓存中的是什么?只有数组所包含的引用或这些引用才会被解引用,并且对象也会被加载到缓存中?

Java(JVM)是​​否实现了某种软件预取?如果没有,是否有提供软件预取的库?

java jvm jvm-hotspot prefetch java-memory-model

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

发生在Java Memory Model之前和程序顺序

我有一些关于程序顺序以及它如何影响JMM中的重新排序.

在Java内存模型中,程序顺序(po)被定义为程序中每个线程中的操作的总顺序.根据JLS,这会导致发生前(hb)边缘:

如果x并且y是同一个线程的动作并且在程序顺序x之前y,那么hb(x,y)(即x发生在之前y).

所以对于一个简单的程序P:

  initially, x = y = 0
     T1     |     T2
 -----------|-----------
  1. r1 = x | 3. r2 = y  
  2. y = 1  | 4. x = r2
Run Code Online (Sandbox Code Playgroud)

我认为po(1,2)po(3,4).因此,hb(1,2)hb(3,4).

现在假设我想重新排序其中一些语句,给我P':

  initially, x = y = 0
     T1     |     T2
 -----------|-----------
  2. y = 1  | 3. r2 = …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading java-memory-model

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

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

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

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

我已经看过这个答案和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
查看次数