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