I am having doubts about the volatile keyword in Java when it comes to arrays (after reading a few questions here and specially this document ).
I have a series of threads reading information from an int array named cardArray, and if an entry does not exist in the array I want to create it. What I use for that is a synchronized method like:
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) is a method which returns the position of such unique id in the array or -1 if the array does not exist. cardArray was declared like:
protected volatile int[] cardArray = new int[10];
The idea behind this is that two threads may want to make the array grow at the same time. Since the growArray() method is synchronized, they will have to make it one by one. Once the first thread makes the array grow, the subsequent threads should not do it, since getIndex(id) should indicate that the id already exists. However, the fact that is the array what is declared as a volatile and not its elements makes me suspicious about if this will be the actual behavior.
Is this what will happen or may the following threads accessing growArray() still try to make the array grow? If so, is there any alternative apart from atomic arrays? I was thinking (in case this does not work as I want) to add cardArray = cardArray after writing the element, but I do not know if it would make a difference.
getIndex(int)do?getIndex(int id)searches the array to see if id is already contained as an entry (for loop, array is not sorted). If it is, it returns its index. If it is not, -1.HashSetor one of the queues, depending on requirements. IsgetIndex()synchronized? Do you call it anywhere else? Do any other (non-synchronized?) functions interact with the array? If the answers are all no, you needn't worry (and might as well make the array synchronized). Otherwise, you probably need some additional checking.