在通过 Brian Goetz 实践 Java Concurrency 时,我遇到了以下行:
当一个变量被多个线程读取并被至少一个线程写入时,就会发生数据竞争,但读取和写入不是 按发生前排序的。正确同步的程序是没有数据竞争的程序;正确同步的程序表现出顺序一致性,这意味着程序中的所有操作似乎都以固定的全局顺序发生。
我的问题是,乱序是在 java 或其他编程语言中写入数据竞争条件的唯一原因吗?
更新
好的,我对数据竞争进行了更多调查,并从oracle 官方网站上发现了以下内容:
线程分析器检测在多线程进程执行期间发生的数据竞争。在以下情况下会发生数据竞争:
- 单个进程中的两个或多个线程同时访问同一内存位置,并且
- 至少其中一项访问是用于写入的,并且
- 线程没有使用任何独占锁来控制它们对该内存的访问。
当这三个条件成立时,访问的顺序是不确定的,并且根据该顺序,每次运行的计算可能会给出不同的结果。一些数据竞争可能是良性的(例如,当内存访问用于忙等待时),但许多数据竞争是程序中的错误。
在这一部分中,提到:访问的顺序是不确定的
它是在谈论线程访问内存位置的顺序吗?如果是,那么同步永远不会保证线程访问代码块的顺序。那么,同步如何解决数据竞争的问题呢?