1. 程式人生 > >CopyOnWriteArrayList類set方法疑惑?

CopyOnWriteArrayList類set方法疑惑?

在淘寶內網有位同事提了一個很好的問題,大家能否幫忙解答下?

在CopyOnWriteArrayList類的set方法中有一段setArray(elements)程式碼,實際上這段程式碼並未對elements做任何改動,實現的volatile語意並不對CopyOnWriteArrayList例項產生任何影響,為什麼還是要保留這行語句?見以下程式碼紅體部分:

    /** The array, accessed only via getArray/setArray. */
    private volatile transient Object[] array;

    /**
     * Replaces the element at the specified position in this list with the
     * specified element.
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E set(int index, E element) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            E oldValue = get(elements, index);

            if (oldValue != element) {
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len);
                newElements[index] = element;
                setArray(newElements);
            } else {
                // Not quite a no-op; ensures volatile write semantics
                setArray(elements);
            }
            return oldValue;
        } finally {
            lock.unlock();
        }
    }

    /**
     * Sets the array.
     */
    final void setArray(Object[] a) {
        array = a;
    }

    /**
     * Gets the array.  Non-private so as to also be accessible
     * from CopyOnWriteArraySet class.
     */
    final Object[] getArray() {
        return array;
    }

這個問題在concurrency-interest郵件列表裡也有人討論: