Java 读/写数组中的元素是原子操作吗?
我有多个线程从一个标记为final的共享数组访问元素(我永远不会尝试将另一个数组分配给它)。我需要同步什么吗?我可以假设对元素的读/写是原子的吗 除非数组的类型为long或double,否则写入是原子的。但是,原子属性对您没有帮助,因为不能保证写入对其他线程可见 如果数组是引用类型,问题就更严重了,因为其他线程可能会看到对象被撕裂:一些字段可见,一些字段不可见 为了安全地共享元素的随机访问集合,您需要在普通的Java 读/写数组中的元素是原子操作吗?,java,synchronization,thread-safety,Java,Synchronization,Thread Safety,我有多个线程从一个标记为final的共享数组访问元素(我永远不会尝试将另一个数组分配给它)。我需要同步什么吗?我可以假设对元素的读/写是原子的吗 除非数组的类型为long或double,否则写入是原子的。但是,原子属性对您没有帮助,因为不能保证写入对其他线程可见 如果数组是引用类型,问题就更严重了,因为其他线程可能会看到对象被撕裂:一些字段可见,一些字段不可见 为了安全地共享元素的随机访问集合,您需要在普通的ArrayList周围使用synchronizedList包装,或者使用无锁的CopyO
ArrayList
周围使用synchronizedList
包装,或者使用无锁的CopyOnWriteArrayList
如果您对数组的固定大小没有意见(看起来是这样),那么也可以查看
AtomicReferenceArray
,因为它允许原子比较和设置以及get和set操作,这可能会使您在不需要锁的情况下进一步实现所需功能。除非数组类型为long或double,否则写入操作是原子的。但是,原子属性对您没有帮助,因为不能保证写入对其他线程可见
如果数组是引用类型,问题就更严重了,因为其他线程可能会看到对象被撕裂:一些字段可见,一些字段不可见
为了安全地共享元素的随机访问集合,您需要在普通的ArrayList
周围使用synchronizedList
包装,或者使用无锁的CopyOnWriteArrayList
如果您对数组的固定大小没有意见(看起来是这样),那么也可以查看
AtomicReferenceArray
,因为它允许原子比较和设置以及get和set操作,这可能会使您在不需要锁的情况下进一步实现所需功能。因为您有多个线程可以读取和写入向量的元素,所以当一个线程读取时,另一个线程可能会写入相同的单元。放置一个同步块。
伪代码示例:
public void get(index i){
synchronized(..){
//your code
}
}
由于有多个线程可以读取和写入向量的元素,因此当一个线程读取时,另一个线程可能会写入同一个单元。放置一个同步块。 伪代码示例:
public void get(index i){
synchronized(..){
//your code
}
}
这是一个字符串数组。它与int/long/double相同吗?因为字符串是不可变的。字符串是一种特殊情况,因为它可以通过数据竞争安全地发布。但是,引用本身的可见性问题不会消失。
AtomicReferenceArray
在这里可能比列表
更合适。将数组声明为volatile如何?@mac这只会使包含数组引用的变量变得不稳定。它对数组本身没有影响。它是一个字符串数组。它与int/long/double相同吗?因为字符串是不可变的。字符串是一种特殊情况,因为它可以通过数据竞争安全地发布。但是,引用本身的可见性问题不会消失。AtomicReferenceArray
在这里可能比列表
更合适。将数组声明为volatile如何?@mac这只会使包含数组引用的变量变得不稳定。它对数组本身没有影响。