Java 创建新线程是否会产生刷新缓存的副作用?

Java 创建新线程是否会产生刷新缓存的副作用?,java,multithreading,concurrency,thread-safety,Java,Multithreading,Concurrency,Thread Safety,我想知道在Java中创建新线程是否会触发缓存刷新。假设我这样做,按照以下顺序: 线程运行并设置变量X 该线程创建一个新线程 新线程访问X 我的问题是:新线程(无论是在创建时还是在开始执行时)是否保证在步骤1中看到旧线程对X所做的更新?我知道,如果旧线程在将来更改X的值,则不能保证新线程会看到这些更改。那很好。我只想知道新线程在启动时是否会看到正确的值,而不需要显式同步 当我第一次决定研究这个话题时,我以为一个简单的谷歌搜索就能立即找到答案,但由于某种原因,我找不到任何解决这个问题的结果。是的,的

我想知道在Java中创建新线程是否会触发缓存刷新。假设我这样做,按照以下顺序:

  • 线程运行并设置变量X
  • 该线程创建一个新线程
  • 新线程访问X
  • 我的问题是:新线程(无论是在创建时还是在开始执行时)是否保证在步骤1中看到旧线程对X所做的更新?我知道,如果旧线程在将来更改X的值,则不能保证新线程会看到这些更改。那很好。我只想知道新线程在启动时是否会看到正确的值,而不需要显式同步

    当我第一次决定研究这个话题时,我以为一个简单的谷歌搜索就能立即找到答案,但由于某种原因,我找不到任何解决这个问题的结果。

    是的,的确如此

    在java中,有一个“before”关系指定两个动作之间可见的内存效果。如果“A发生在B之前”,则动作B保证看到动作A所做的所有更改

    启动线程会在“thread.start()”调用和在新线程上执行的所有代码之间创建“before”关系。因此,新线程保证在第一个线程上看到更改变量X的内存效果

    有关“先发生后发生”关系的快速概述,请参阅java.util.concurrent包概述的一部分。在您的案例中,有趣的是:

    • 线程中的每个动作都发生在该线程中的每个动作之前,该线程中的每个动作都是按照程序的顺序稍后出现的
    • 对线程的启动调用发生在已启动线程中的任何操作之前
    如果您好奇,请访问更多链接:

    • Java内存模型如中所述

    如果你能让所讨论的变量变得易变,为什么还要依赖这些模糊的保证(如果它们存在的话)?@delnan:这里没有模糊的东西。Java语言规范中明确规定了这种行为。现在一个更模糊的保证问题可能是:“a写X;B创建;C读X”--这种行为是定义的吗?:-)@pst:不确定B是如何关联的。在这种情况下,C保证看到默认值或由A编写的值,但没有指定哪个值。(假设没有其他写入X的操作,并且“A写入X”和“C读取X”操作不通过任何其他方式同步,例如使用volatile)。@pst:创建线程和等待(加入)线程时都有同步。不过,这是一个不错的答案,通读这个概要让我不清楚它是否定义为:线程存在,
    A,B,变量X未知
    <代码>A写X;B创造C;C读X。请注意,
    C
    是由
    B
    创建的,而不是
    A
    ——因此A和C之前没有发生过什么?(请注意,这不是原始问题所问的,这个问题确实回答了这个问题,只是沉思而已!:-)@pst:是的,你是对的。在本例中,“A写入X”和“C读取X”操作之间没有“之前发生”。@PeterŠtibraný:你的意思是“B创建C”和“C读取X”之间没有“之前发生”,但“A写入X”和B或C中的任何其他操作之间没有。作为参考,我检查了链接文档中记录线程同步的特定部分。start():“同步操作导致操作上的synchronized with关系,定义如下:-启动线程的操作与它启动的线程中的第一个操作同步。”[来自17.4.4]