我想知道以下结构是否是安全线程。我知道我应该同步对 enc
的所有访问(读、写、加/减)。但我想知道 boolean 数组是否安全。它们通过许多不同的线程不断变化。我当然谈论的是数组元素而不是数组引用。
public class SimBox {
public static final int HP = 100;
public static final int LP = 35;
public static volatile boolean[] ins = new boolean[16];
public static volatile boolean[] outs = new boolean[16];
public static volatile int enc = 0;
}
注意:在这种情况下,我不需要重新初始化数组。我只读取和写入它们的元素。我想知道我是否也应该宣布它们为最终版本?!
它们有什么用?
模拟硬件/机械机器的运动。
- 有一些线程根据以下内容更新
outs
字段 ins字段的实时内容。 - 有些线程会根据
enc
值和其他一些外部因素更改ins
字段。 - 有一个独特的线程,可以根据输出和输入线程通过添加/减去
HP
或LP
来更新enc
。 - 还有一些其他线程读取
enc
值,并为程序的其他部分或更改outs
做出决定。 - 所有这些数据最多在 40 毫秒后可供读/写,这一点非常重要。否则就会出现一些异常情况。
最佳答案
Does volatile synchronise an array of atomic data types?
没有。但是,您的示例未使用原子数据类型。
I wonder if the following structure is safe-thread (sic).
不,事实并非如此。有很多方法可以访问/更新该数据结构,但这些方法不是线程安全的。
I wonder if I should declare them final too?!
这将是一个好主意,但它不会使数组成为线程安全的。
<小时/>如果您想实现对数组的线程安全访问和更新(不使用synchronized
),您应该查看原子数组类。其中共有三个:AtomicIntegerArray
、AtomicLongArray
和 AtomicReferenceArray
。您还可以使用普通(非同步)AtomicBoolean 数组...前提是该数组已安全发布到线程并且从未被线程更新。
但我不清楚被大量线程“随机”更改的原子数组是否可用于您的目的。首先,原子数组不提供一种方法来获取用于分析目的的一致的数组快照。实现此目的的唯一方法是在(假设的)代码检查原子数组时“暂停”或“停止”所有线程。
如果您需要在不显式停止/暂停一切的情况下获得一致的快照,那么最好使用同步
而不是“原子”类型。
关于java - volatile 是否同步原子数据类型的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20753401/