집합 프레임 워 크 깊이 있 는 CopyOnWriteArray List 소스 분석

CopyOnWriteArrayList 개요
CopyonWriteArrayList 는 ArrayList 의 안전 한 스 레 드 변종 입 니 다.
CopyOn Write Array List 와 Array List 는 배열 을 복사 하고 자 물 쇠 를 추가 할 지 여부 에 달 려 있다.
CopyOnWriteArrayList 는 말 그대로 쓰기 시 복 제 된 ArrayList 로,용기 의 요 소 를 수정 할 때 원 배열 에서 직접 수정 하 는 것 이 아니 라 한 배열 을 복사 한 다음 복 사 된 배열 에서 수정 하고 수정 한 후 이 를 원 배열 의 인용 에 할당 한 다 는 뜻 이다.이렇게 하면 읽 기와 쓰기 의 분 리 를 나타 내 고 언제든지 용기 에 대해 읽 을 수 있다.
구성원 변수
여기 서 흔히 볼 수 있 는 몇 가지 특성 을 분석 해 보 자.
 transient final ReentrantLock lock = new ReentrantLock();
//   CopyOnWriteArrayList     ,                    。
private volatile transient Object[] array;

이것 이 바로 원수 그룹 입 니 다.우 리 는 Array List 와 다른 점 은 volatile 속성 을 증가 시 켰 다 는 것 을 발 견 했 습 니 다.
이게 무슨 소 용이 있 습 니까?
Volaile 은 약 한 단계 의 synchronized 에 해당 하 며 가시 성 을 제공 합 니 다.다 중 스 레 드 실행 환경 에서 모든 스 레 드 를 볼 수 있 습 니 다.이것 은 모든 스 레 드 가 얻 은 데이터 가 일치 하 는 것 을 보장 합 니 다.
자 물 쇠 는 두 가지 단계 의 메커니즘 을 제공 했다.상호 배척 과 가시
서로 배척 하 는 것 은 한 스 레 드 가 수 정 된 데 이 터 를 수정 할 때 다른 스 레 드 는 이 데 이 터 를 방문 할 수 없다 는 것 이다.
이 를 통 해 알 수 있 듯 이 한 스 레 드 가 데 이 터 를 수정 할 때 다른 스 레 드 가 받 은 값 은 모두 일치 하 다.모든 스 레 드 가 volatile 의 최신 값 을 자동 으로 가 져 올 수 있다 는 것 이다.
그래서 synchronized 는 array 가 쓸 때의 원자 성 을 확보 하고 volatile 은 array 의 가시 성 을 확보한다 고 할 수 있 습 니 다.
----------------------------------------------------------------------------------------------------------------------------
     //    
    final Object[] getArray() {
        return array;
   }
      
     //    
    final void setArray(Object[] a) {
        array = a;
    }

읽 기: 

 /**
     * {@inheritDoc}
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        return (E)(getArray()[index]);
    }

         ,       。

쓰기:
    //                 
    public E set(int index, E element) {
	final ReentrantLock lock = this.lock;
	lock.lock();
	try {
	    Object[] elements = getArray();
         //    
	    Object oldValue = 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 (E)oldValue;
	} finally {
	    lock.unlock();
	}
   }
   
   
   
     //    
    public boolean add(E e) {
	final ReentrantLock lock = this.lock;
	lock.lock();
	try {
	    Object[] elements = getArray();
	    int len = elements.length;
  <span style="white-space:pre">	</span>//                  
	    Object[] newElements = Arrays.copyOf(elements, len + 1);
  <span style="white-space:pre">	</span>//          
	    newElements[len] = e;
  <span style="white-space:pre">	</span>//    
	    setArray(newElements);
	    return true;
	} finally {
	    lock.unlock();
	}
    }
   
   

     //         
    public E remove(int index) {
	final ReentrantLock lock = this.lock;
	lock.lock();
	try {
	    Object[] elements = getArray();
	    int len = elements.length;
  <span style="white-space:pre">		</span>//    
	    Object oldValue = elements[index];
	    int numMoved = len - index - 1;
	    if (numMoved == 0)
  <span style="white-space:pre">		</span>//      
		setArray(Arrays.copyOf(elements, len - 1));
	    else {
 <span style="white-space:pre">		</span> //     
		Object[] newElements = new Object[len - 1];
  <span style="white-space:pre">		</span>// 0    index  
		System.arraycopy(elements, 0, newElements, 0, index);
 <span style="white-space:pre">		</span> //  
		System.arraycopy(elements, index + 1, newElements, index,
				 numMoved);
 <span style="white-space:pre">		</span> //    
		setArray(newElements);
	    }
	    return (E)oldValue;
	} finally {
	    lock.unlock();
	}
       }

위의 세 가지 업데이트,추가,삭제 방법 을 보면 CopyOn Write Array List 는 원래 배열 을 수정 하 는 과정 에서 Array List 보다 두 가지 일 을 더 한 것 을 발견 했다.
1.잠 금 추가:내 가 배열 을 수정 할 때 다른 사람 이 수정 할 수 없 도록 보장 합 니 다.
2.복사 배열:어떤 방법 이 든 복사 배열 이 필요 합 니 다.
위의 두 가지 일 은 CopyOn Write Array List 가 다 중 스 레 드 환경 에서 자 유 롭 게 대응 할 수 있 도록 확보 했다.
----------------------------------------------------------------------------------------------------------------------------------------------------
교체 기:
CopyOn WriteArray List 의 교체 기 는 빠 른 실패 가 아 닙 니 다.즉,Concurrent ModificationException 이상 을 던 지지 않 습 니 다.수정 할 때 복사 배열 에 영향 을 주지 않 았 기 때문이다.교체 기 에 잠 금 장치 가 없 음 을 알 수 있 기 때문에 읽 기 만 제공 하고 수정 과 삭 제 를 추가 하 는 것 은 지원 되 지 않 습 니 다.
public ListIterator<E> listIterator() {
        return new COWIterator<E>(getArray(), 0);
   }
private static class COWIterator<E> implements ListIterator<E> {
        //      
        private final Object[] snapshot;
        //  
        private int cursor;

        private COWIterator(Object[] elements, int initialCursor) {
            cursor = initialCursor;
            snapshot = elements;
        }

        public boolean hasNext() {
            return cursor < snapshot.length;
        }

        public boolean hasPrevious() {
            return cursor > 0;
        }

        public E next() {
	    if (! hasNext())
                throw new NoSuchElementException();
	    return (E) snapshot[cursor++];
        }

        public E previous() {
	    if (! hasPrevious())
                throw new NoSuchElementException();
	    return (E) snapshot[--cursor];
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor-1;
        }

        //     
        public void remove() {
            throw new UnsupportedOperationException();
        }

  //     
        public void set(E e) {
            throw new UnsupportedOperationException();
        }
      
  //     
        public void add(E e) {
            throw new UnsupportedOperationException();
        }
       }

CopyOnWriteArrayList 의 부족 함:
데이터 일치 성 문제:한 스 레 드 가 수정 되 고 있 고 다른 스 레 드 가 지금 오래된 데 이 터 를 읽 습 니 다.즉,데이터 의 일치 성 을 보장 할 수 없습니다.
메모리 문제:
추가,수정,삭제 작업 에서 대량의 복사 배열 이 있 습 니 다.메모리 가 시간 이 지나 면 메모리 에 많은 새로운 배열 이 생 겨 서 일련의 young 을 미리 촉발 합 니 다. GC 와 Full GC 는 CopyOnWriteArrayList 가 읽 기 에 더 적합 하고 대량의 수정 에 적합 하지 않다 는 것 을 설명 했다.
참고:
동시 다발 얘 기.-자바 의 Copy-On-Write 용기.
CopyOnWriteArrayList 소스 코드 를 보고

좋은 웹페이지 즐겨찾기