Java多线程读取信息

Java多线程读取信息,java,multithreading,memory,Java,Multithreading,Memory,有一天我在想线程,我开始怀疑多个线程是否可以访问相同的信息(不使用synchronized(lock)),假设它们根本不修改它 例如,10个线程读取1个类,该类由于我们将调用M的线程而一直在更改。这些线程调用访问器从该类获取信息,但不以任何方式修改信息。 同时,线程M偶尔会修改这个类中的数据(这会在10个线程“重新启动”后更改计算结果) 会有问题吗?问题是其中一个线程正在“返回”线程M已修改的信息。除此之外,是否还会有这样一种情况:访问一段信息仍然会导致Java将该信息放回内存,即使它从未被修改

有一天我在想线程,我开始怀疑多个线程是否可以访问相同的信息(不使用synchronized(lock)),假设它们根本不修改它

例如,10个线程读取1个类,该类由于我们将调用M的线程而一直在更改。这些线程调用访问器从该类获取信息,但不以任何方式修改信息。
同时,线程M偶尔会修改这个类中的数据(这会在10个线程“重新启动”后更改计算结果)

会有问题吗?问题是其中一个线程正在“返回”线程M已修改的信息。除此之外,是否还会有这样一种情况:访问一段信息仍然会导致Java将该信息放回内存,即使它从未被修改过

谢谢


编辑:在调用访问者之前使用final是否安全?喜欢最终对象t=someAccessor()

否,线程读取单个值不会有问题,除非写入操作不是原子操作时,读取数据会出现一致性问题,尤其是在读取多个值时

想象一下,就像一个线程正在读取两个数据点(比如x和y)一样,主线程正在更新x和y的值。我们会说x从1变为10,y从2变为20

可能发生以下情况:

  • 主线程将X更新为10
  • 工作线程读取X并将其存储到自己的内存中以供以后处理。它看到的值为10
  • 然后工作线程读取Y等于2(而不是20),并将其存储以供以后处理
  • 主线程将Y更新为20
  • 现在,工作线程正在处理不一致的数据。如果这是对机器人手臂的控制,而不是(1,2)和(10,20)两个漂亮的点,则手臂会猛拉到(10,2)并造成伤害。如果这是一张图表,可能会显示随机的无关点

    尽管使用了
    volatile
    关键字,这种情况还是会发生(在某些JVM上可能会加剧)

    对于任何给定的读或写操作,都不太可能发生这种情况(除非两个线程中都有紧循环),但一次不一致的读操作甚至可能会导致错误的输出、程序崩溃甚至崩溃


    您可以将坐标封装在一个简单的POJO(包含字段、构造函数、getter和setter的类)中,并使用
    AtomicReference

    以原子方式交换坐标,啊,我完全忘记了会发生这样的事情!谢谢你的快速回复。是否可以同时更新X和Y以避免发生这种情况?或者在线程M修改这些坐标时“暂停”其他线程?@TheOverWhelming是的,可以通过使用同步块暂停其他线程。如果主线程正在同步块中更新X和Y,则为同一锁进入同步块的线程将“暂停”,直到主线程退出该块。但是,线程将等待彼此读取。我将在几分钟后在我的帖子中编辑一个更好的解决方案。你做得非常彻底。我们可以用“竞争条件”一词来概括它。