gpt4 book ai didi

java - volatile 会保护我免受所有幕后多线程危害吗?

转载 作者:太空狗 更新时间:2023-10-29 14:15:49 25 4
gpt4 key购买 nike

我以前认为多线程的危害只有两个:

  1. 竞争条件:一个线程读取x,然后在它可以写回另一个线程之前写入x
  2. 不稳定状态:一个线程写入xy,但在这两者之间写入另一个线程读取x的新值和 y 的旧值,即使这些变量应该一起改变。

我想如果我能推断出这些事情不会发生,我就不需要同步。但是来自an argument over the D language forums我从编译器、CPU 和内存在幕后的工作方式了解到可能存在其他危险:

  1. 编译器和 CPU 都可以以不影响单线程执行但会破坏我关于非同步线程安全的推理的方式更改指令顺序。例如,可以分配一个对象并将其赋值给线程共享变量,然后才会调用构造函数。这在单线程中应该无关紧要,但在多线程中,另一个线程现在可以访问未初始化的对象。
  2. 缓存意味着即使操作顺序正确,全局内存和两个线程使用的本地缓存之间的同步也会扰乱一个线程可以看到另一个线程更改的顺序。
  3. 未对齐的指针大小的写入不是原子的,在某些体系结构中甚至对齐的也可能不是原子的,因此当其他线程读取指针时,指针本身可能已损坏(=处于不稳定状态),因为写入它的线程只写了一半字节。

我现在在一个 Android 项目上工作,我又一次遇到了类似的问题 - 我可以推断出一些函数在竞争条件和不稳定状态下是安全的,但不能推断出这三种幕后危险。

我遇到过 Java volatile 成员字段,据我所知,它使用内存屏障来防止 CPU 打乱执行顺序(显然编译器不会打乱它如果它阻止 CPU 这样做)那么它应该解决第一个危险。但是另外两个呢?

  • 它是否解决了缓存问题?缓存不是由操作系统负责吗?它是否向操作系统发出信号,迫使其刷新缓存?
  • 它是否解决了非原子写入问题?它是否强制变量对齐并使用 JVM 的运行时知识来使用同步,即使是对齐的指针大小的写入也不是原子的?

换句话说 - 如果我可以推断竞争条件和不稳定状态不是问题,并将共享变量标记为 volatile,那么不使用同步是否安全?

最佳答案

我不知道第一个和第三个问题(如果你确定的话,关于第一个问题的一些链接会很好)但我确信它解决了你的第二个问题,因为 volatile 确保刷新本地缓存。

参见 thisthis关于这个话题。

更新

我想我找到了您问题的完美链接:

http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html#ixzz2vjymNleY

<强>1。关于重新排序

By the way use of volatile keyword also prevents compiler or JVM from reordering of code or moving away them from synchronization barrier.

<强>2。关于缓存

Volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache value of this variable and always read it from main memory

<强>3。关于原子读写

In Java reads and writes are atomic for all variables declared using Java volatile keyword (including long and double variables).

关于java - volatile 会保护我免受所有幕后多线程危害吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22346385/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com