【发布时间】:2015-12-17 01:32:20
【问题描述】:
我找到了以下 Java 代码。
for (int type = 0; type < typeCount; type++)
synchronized(result) {
result[type] += parts[type];
}
}
其中result 和parts 是double[]。
我知道基本类型的基本操作是线程安全的,但我不确定+=。如果上面的synchronized是必要的,是否有更好的类来处理这种操作?
【问题讨论】:
-
操作不是原子,所以可能需要外部同步。
-
您对所谓的基本操作也有些困惑(我假设您的意思是读取和写入)。确实,原始类型(例如 int)的读取是原子的,但这不会使其成为线程安全的。线程安全也涉及可见性。因此,即使线程 A 原子地将整数的值设置为 42,也不能保证线程 B 在之后执行原子读取时可以看到该值。
-
@JanusVarmarken:回复:“原始类型(比如 int)的读取确实是原子的”:是的,除了 long 和 double;见docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.7。
-
将
synchronized放在循环周围可能会有所帮助 - 现在,您正在进入和离开循环的每次迭代的关键部分,这可能会主导运行时完全为了这段代码。 -
@assylias:这不是原子性的充分理由,实际上至少有两次读取,甚至可能更多(读取地址、读取偏移量、加载值,以及两次)。即使对于整个表达式或完整的循环,语言标准仍然可以要求原子性。
标签: java multithreading