java - 在java中读取 double 可以是线程安全的吗?

标签 java multithreading

假设我有一个类如下:

public class vector{
    public vector(double x, double y){
        this.x = x;
        this.y = y;
   }
    public double getDist() {
       return Math.sqrt(x*x + y*y);
   }
}

这段代码在线程中运行安全吗?我有点困惑,因为我知道 double 的读法 不是原子的,但是因为这个类没有 setter 或 getter,所以需要做些什么来确保这是线程安全的?

谢谢

最佳答案

I am a little confused because I know reads of doubles are not atomic, but because this class has no setters or getters is anything needed to be done in order to ensure this is thread safe?

是的,您需要确保 xy标记为final 。这与 double 无关。然而。 finalvector 时,字段保证被完全初始化。 (应该是 Vector 顺便说一句)已构建。没有 final如果您共享 vector 的实例如果没有同步,编译器可以重新排序字段初始化超过构造函数完成时的点和 xy字段可能未初始化或部分初始化。所以另一个线程可能会看到 xy为 0 或仅更新其中一个单词。欲了解更多信息,请参阅Constructor synchronization in Java

如果您正在使用可变字段(不能是 final ),那么无论 double 是否是否会完全更新取决于您所运行的架构。为了安全起见,你必须让它们 volatile以确保它们在更改时得到完全更新和发布。

正如 @Voo 指出的,如果您正在更新 x然后y那么这是 2 个单独的操作,您的距离计算可能只会看到两个字段之一被更新 - 即使它们都是 volatile 。如果您需要它是原子的,那么您应该使用 AtomicReference并有一个小容器类,可以同时容纳两者 xyAtomicReference包装 volatile Object .

类似于:

 private final AtomicReference<XAndY> xyRef = new AtomicReference<XAndY>();
 ...
 public void setXAndY(double x, double y) {
     xyRef.set(new XAndY(x, y));
 }
 ...
 public double getDist() {
    // get a local instance of our object which is atomic
    XAndY xAndY = xyRef.get();
    return Math.sqrt(xAndY.x * xAndY.x + xAndY.y * xAndY.y);
 }
 ...
 private static class XAndY {
     double x;
     double y;
 }

关于java - 在java中读取 double 可以是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22055829/

相关文章:

java - 如何用docx4j替换标题和表格中的变量?

java - setProgressbar 未在 Activity 上运行的线程中更新 getView 内部?

c - 与 pthreads 不一致的运行时

java - 如何在java中使用注解自动设置和获取?

c# - 访问其他线程wpf中的ui元素

multithreading - 在 Linux 中使用多队列 NIC

.net - MS 研究国际象棋的替代方案?

java - Retrofit 2 类文件问题

java - 如何将字符串键和浮点值的 Json 树转换为 Map

java - 如果是字符串,应该如何使用同步?