当涉及数组时,我对Java中的volatile关键字有疑问(在这里读了几个问题,特别是本文件 )。
我有一系列线程从名为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的位置,如果数组不存在,则返回-1。cardArray被声明为:protected volatile int[] cardArray = new int[10];
背后的想法是,两个线程可能希望使数组同时增长。由于growArray()方法是同步的,所以它们必须一个一个地实现它。一旦第一个线程使数组增长,随后的线程就不应该这样做,因为getIndex( id )应该表明id已经存在。然而,这是一个被声明为volatile的数组,而不是它的元素,这让我怀疑这是否是实际的行为。
这是将要发生的情况,还是下面访问growArray()的线程仍然试图使数组增长?如果是这样的话,除了原子数组之外,还有其他选择吗?在编写元素之后,我想(万一这不像我想要的那样)添加cardArray = cardArray,但我不知道它是否会产生影响。
发布于 2014-06-13 13:30:37
根据您的需求,您可能希望使用ArrayList、HashSet或LinkedHashSet。如果要用Java编写大量代码,那么熟悉Java集合库将真正受益。
以下是一些可供选择的办法的说明:
http://docs.oracle.com/javase/tutorial/collections/implementations/index.html
如果您决定使用ArrayList,您的实现如下所示:
// This is how you might create your list.
private List<Integer> myList = new ArrayList<Integer>();
public synchronized void growArray(int id) {
if( ! cardList.contains(id) ){
cardList.add(id);
}
}如果您使用HashSet (它保证唯一性并自动增长),您可能会这样做:
// This is how you might create your list.
private Set<Integer> myList = new HashSet<Integer>();
public synchronized void growArray(int id) {
cardList.add(id);
}希望这能有所帮助!
发布于 2014-06-13 13:26:01
这是将要发生的情况,还是以下访问growArray()的线程仍然试图使数组增长?
如果一个线程存在getIndex(id) == -1为false的方法,那么任何随后进入该方法的线程也会看到此更新。这是因为方法是同步的。实际上,您可以完全消除易失性,而且它仍然可以工作。
但是,由于您正在更新易失性,任何非synchronized访问都将受益于易失性写入,因此您可能希望保持此方式声明它。
https://stackoverflow.com/questions/24205270
复制相似问题