【发布时间】:2014-08-04 00:14:45
【问题描述】:
当涉及到数组时,我对 Java 中的 volatile 关键字有疑问(在阅读了这里的几个问题,特别是 this document 之后)。
我有一系列线程从名为 cardArray 的 int 数组读取信息,如果数组中不存在条目,我想创建它。我使用的是一种同步方法,例如:
public synchronized void growArray(int id) {
if(getIndex(id) == -1) {
cardArray = Arrays.copyOf(cardArray, cardArray.length + 1);
cardArray[cardArray.length - 1] = id;
}
}
getIndex(int id) 是一种返回此类唯一 id 在数组中的位置的方法,如果数组不存在,则返回 -1。 cardArray 声明如下:
protected volatile int[] cardArray = new int[10];
这背后的想法是两个线程可能想让数组同时增长。既然growArray()方法是同步的,就得一一搞定。一旦第一个线程使数组增长,后续线程不应该这样做,因为 getIndex(id) 应该指示 id 已经存在。然而,声明为volatile 的数组而不是它的元素这一事实让我怀疑这是否是实际行为。
这是会发生什么,还是以下线程访问growArray() 仍会尝试使数组增长?如果是这样,除了原子数组之外还有其他选择吗?我正在考虑(以防万一这不起作用)在编写元素后添加cardArray = cardArray,但我不知道它是否会有所作为。
【问题讨论】:
-
为什么是数组?还有其他更适合调整大小的数据结构。另外,
getIndex(int)是做什么的? -
我不是 Java 数据结构方面的专家,我可以使用什么其他结构来有效调整大小?
getIndex(int id)搜索数组以查看 id 是否已作为条目包含(for 循环,数组未排序)。如果是,则返回其索引。如果不是,-1。 -
我会使用
HashSet或其中一个队列,具体取决于要求。getIndex()同步了吗? Do you call it anywhere else? 是否有其他(非同步?)函数与数组交互?如果答案都是no,你不必担心(不妨让数组同步)。否则,您可能需要进行一些额外的检查。 -
@nosid 是的,读取方法(它们都没有写入)。
标签: java arrays multithreading volatile