标签: java-memory-model

关于可见性及时性的易失性的详细语义

考虑一下volatile int sharedVar.我们知道JLS为我们提供了以下保证:

  1. 写入线程的每个动作在w其写入值之前isharedVar程序顺序happens-before写入动作;
  2. 的值写入i通过w happens-before的成功读取isharedVar由读取线程r;
  3. 成功读取isharedVar由读线程r happens-before的所有后续行动r的程序顺序.

然而,仍有给出没有挂钟时间的保证,当读线程将观察值i.一个完全不会让读取线程看到该值的实现仍然符合此契约.

我已经考虑了一段时间,我看不到任何漏洞,但我认为必须有.请指出我的推理漏洞.

java volatile java-memory-model

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

CompletableFuture,可变对象和内存可见性

我试图理解CompletableFutureJava 8 如何与Java内存模型交互.在我看来,对于程序员的理智,理想情况下应该成立:

  1. 完成任务的线程中的操作CompletableFuture - 在执行任何完成相关的阶段之前
  2. 在该线程操作注册完成创建依赖阶段发生,之前完成执行依赖阶段

java.util.concurrent文档中有一条说明:

在提交Runnable到执行之前的线程中的操作Executor - 在执行开始之前.同样的Callables提交给ExecutorService.

这表明第一个属性为true,只要完成未来的线程执行完成依赖阶段或将其提交给Executor.另一方面,在阅读CompletableFuture文档后,我不太确定:

为非异步方法的依赖完成提供的动作可以由完成当前的线程执行CompletableFuture,或者由完成方法的任何其他调用者执行.

这让我想到了我的问题:

  1. 这两个假设属性是否真实?
  2. 在使用时,是否有任何关于存在或缺乏内存可见性保证的特定文档CompletableFuture

附录:

在具体示例中,请考虑以下代码:

List<String> list1 = new ArrayList<>();
list1.add("foo");

CompletableFuture<List<String>> future =
        CompletableFuture.supplyAsync(() -> {
            List<String> list2 = new ArrayList<>();
            list2.addAll(list1);
            return list2;
        });
Run Code Online (Sandbox Code Playgroud)

能够保证所有的加入"foo"list1是可见的lambda函数?是否保证添加 …

java java.util.concurrent java-memory-model java-8 completable-future

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

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

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

java multithreading synchronization thread-safety java-memory-model

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

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

Java并发:是最终字段(在构造函数中初始化)是否是线程安全的?

谁能告诉我这个类是否是线程安全的?

class Foo {

    private final Map<String,String> aMap;

    public Foo() {
        aMap = new HashMap<String, String>();
        aMap.put("1", "a");
        aMap.put("2", "b");
        aMap.put("3", "c");
    }

    public String get(String key) {
        return aMap.get(key);
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑:我不能澄清这个问题.根据JMM FAQ:

应提供初始化安全性的新保证.如果一个对象被正确构造(这意味着对它的引用在构造期间不会被转义),那么看到对该对象的引用的所有线程也将看到在构造函数中设置的最终字段的值,而不需要同步.

这让我把这个集合混淆为aMap aMap = new HashMap<String, String>();.所以其他线程可以看到这些

aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
Run Code Online (Sandbox Code Playgroud)

或不 ?

编辑:我发现这个问题与我的问题完全不同

java concurrency java-memory-model

17
推荐指数
2
解决办法
7228
查看次数

为什么在Java内存模型中允许这种行为?

JMM中的因果关系似乎是其中最令人困惑的部分.我有几个关于JMM因果关系的问题,并允许并发程序中的行为.

据我了解,目前的JMM总是禁止因果关系循环.(我对吗?)

现在,根据JSR-133文档,第24页,图16,我们有一个例子,其中:

原来 x = y = 0

线程1:

r3 = x;
if (r3 == 0)
    x = 42;
r1 = x;
y = r1;
Run Code Online (Sandbox Code Playgroud)

线程2:

r2 = y;
x = r2;
Run Code Online (Sandbox Code Playgroud)

直觉上,r1 = r2 = r3 = 42似乎不可能.但是,它不仅被提及,而且在JMM中也被"允许".

对于这种可能性,我无法理解的文件中的解释是:

编译器可以确定分配给的唯一值x是0和42.从那以后,编译器可以推断出,在我们执行的时候r1 = x,我们刚刚执行了42的写入 x,或者我们刚刚读过x和看过价值42.在任何一种情况下,读取x价值42 是合法的.然后可以r1 = x改为r1 = 42; 这将允许y = r1转换为y = 42更早并执行,从而导致相关行为.在这种情况下,y首先提交写入.

我的问题是,它真的是什么样的编译器优化?(我是编译器无知的.)由于42只被写入有条件,当if …

java concurrency compiler-optimization causality java-memory-model

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

最终与波动的保证书,以安全发布对象

从Java并发实践中的书:

要安全地发布对象,必须同时使对象的引用和对象的状态对其他线程可见.正确构造的对象可以通过以下方式安全发布:

  • 从静态初始化程序初始化对象引用

  • 将对它的引用存储到volatile字段或AtomicReference中

  • 将对它的引用存储到正确构造的对象的最终字段中

  • 将对它的引用存储到由
    锁正确保护的字段中.

我的问题是:

  1. 子弹点2和3之间有什么区别?我对volatile方法和final方法在安全发布对象方面的区别感兴趣.
  2. 在第3点中,正确构造的物体的最终场什么意思?在开始项目符号之前,作者已经提到他们正在谈论一个正确构造的对象(我假设它不会让this引用转义).但他们为什么再次提到正确构造的物体呢?

java java-memory-model

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

如果不需要该值,Java 是否允许优化掉易失性读取,同时删除同步之前发生的操作?

以下代码示例显示了一种常见方法,用于演示由于缺少发生之前关系而导致的并发问题。

private static /*volatile*/ boolean running = true;
    
public static void main(String[] args) throws InterruptedException {
    new Thread() {
        @Override
        public void run() {
            while (running) {
                // Do nothing
            }
        }
    }.start();
    Thread.sleep(1000);
    running = false;
}
Run Code Online (Sandbox Code Playgroud)

如果runningvolatile,程序保证在大约一秒后终止。但是,如果running不是volatile,则根本无法保证程序终止(因为在running这种情况下没有发生之前关系或保证变量更改的可见性),而这正是我的测试中发生的情况。

根据JLS 17.4.5,人们还可以通过写入和读取另一个volatile变量来强制执行发生前关系running2,如以下代码示例所示。

private static boolean running = true;
private static volatile boolean running2 = true;
    
public static void main(String[] args) throws InterruptedException {
    new Thread() …
Run Code Online (Sandbox Code Playgroud)

java multithreading volatile java-memory-model happens-before

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

原始数组写入的Java并发可见性

我最近在我的代码库中找到了这个gem:

/** This class is used to "publish" changes to a non-volatile variable.
 *
 * Access to non-volatile and volatile variables cannot be reordered,
 * so if you make changes to a non-volatile variable before calling publish,
 * they are guaranteed to be visible to a thread which calls syncChanges
 *
 */
private static class Publisher {
    //This variable may not look like it's doing anything, but it really is.
    //See the documentaion for this class.
    private volatile AtomicInteger sync …
Run Code Online (Sandbox Code Playgroud)

java concurrency java-memory-model memory-barriers

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

Java final 字段:当前 JLS 是否可能出现“污点”行为

我目前正在尝试了解有关最终字段的 JLS 部分

为了更好地理解 JLS 中的文本,我还在阅读Jeremy Manson(JMM 的创建者之一)撰写的The Java Memory Model

该论文包含让我感兴趣的示例:如果o具有 final 字段的对象对另一个线程可见t两次:

  • o的构造函数完成之前首先“不正确地”
  • o的构造函数完成后的下一个“正确”

然后即使仅通过“正确”发布的路径访问它,也t可以看到半构造的o

这是论文中的部分:

图 7.3:简单最终语义示例

f1 是最后一个字段;它的默认值为 0

主题 1 主题 2 主题 3
o.f1 = 42;
p = o;
freeze o.f1;
q = o;

Run Code Online (Sandbox Code Playgroud)
r1 = p;
i = r1.f1;
r2 = q;
if (r2 == r1)
    k = r2.f1;
Run Code Online (Sandbox Code Playgroud)
r3 = q;
j = r3.f1;



Run Code Online (Sandbox Code Playgroud)

我们假设 r1、r2 和 …

java multithreading final java-memory-model jls

15
推荐指数
2
解决办法
684
查看次数