在淘宝内网有位同事提了一个很好的问题,大家能否帮忙解答下?
在CopyOnWriteArrayList类的set方法中有一段setArray(elements)代码,实际上这段代码并未对elements做任何改动,实现的volatile语意并不对CopyOnWriteArrayList实例产生任何影响,为什么还是要保留这行语句?见以下代码红体部分:
01 |
/** The array, accessed only via getArray/setArray. */ |
02 |
private volatile transient Object[] array; |
03 |
04 |
/** |
05 |
* Replaces the element at the specified position in this list with the |
06 |
* specified element. |
07 |
* |
08 |
* @throws IndexOutOfBoundsException {@inheritDoc} |
09 |
*/ |
10 |
public E set( int index, E element) { |
11 |
final ReentrantLock lock = this .lock; |
12 |
lock.lock(); |
13 |
try { |
14 |
Object[] elements = getArray(); |
15 |
E oldValue = get(elements, index); |
16 |
17 |
if (oldValue != element) { |
18 |
int len = elements.length; |
19 |
Object[] newElements = Arrays.copyOf(elements, len); |
20 |
newElements[index] = element; |
21 |
setArray(newElements); |
22 |
} else { |
23 |
// Not quite a no-op; ensures volatile write semantics |
24 |
setArray(elements); |
25 |
} |
26 |
return oldValue; |
27 |
} finally { |
28 |
lock.unlock(); |
29 |
} |
30 |
} |
31 |
32 |
/** |
33 |
* Sets the array. |
34 |
*/ |
35 |
final void setArray(Object[] a) { |
36 |
array = a; |
37 |
} |
38 |
39 |
/** |
40 |
* Gets the array. Non-private so as to also be accessible |
41 |
* from CopyOnWriteArraySet class. |
42 |
*/ |
43 |
final Object[] getArray() { |
44 |
return array; |
45 |
} |
这个问题在concurrency-interest邮件列表里也有人讨论:
http://cs.oswego.edu/pipermail/concurrency-interest/2010-February/006886.html