Nice programing

Collections.synchronizedList 및 동기화 됨

nicepro 2020. 11. 16. 22:11
반응형

Collections.synchronizedList 및 동기화 됨


List<String> list = Collections.synchronizedList(new ArrayList<String>());
synchronized (list) {
    list.add("message");
}

"synchronized (list) {}"블록이 여기에 정말로 필요합니까?


예제에 넣은대로 동기화 할 필요가 없습니다. 그러나 매우 중요한 것은 목록을 반복 할 때 목록을 동기화해야한다는 것입니다 (Javadoc에 언급 됨).

사용자가이를 반복 할 때 반환 된 목록에서 수동으로 동기화해야합니다.

List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());   
}

synchronized블록 의 정확한 내용에 따라 다릅니다 .

  1. 블록이 목록에서 단일 원자 연산을 수행하는 경우 (예제에서와 같이) synchronized는 불필요합니다.

  2. 블록이 목록에서 여러 작업을 수행하고 복합 작업 기간 동안 잠금을 유지해야하는 경우 에는 불필요한 작업synchronized아닙니다 . 이에 대한 한 가지 일반적인 예는 목록을 반복하는 것입니다.


Collections.synchronizedList add 메서드의 기본 코드는 다음과 같습니다.

public void add(int index, E element) {
    synchronized (mutex) {list.add(index, element);}
}

따라서 귀하의 예에서는 동기화를 추가 할 필요가 없습니다.


또한 예를 들어 Collections.sort ()와 같이 반복자를 사용하는 모든 메서드는 동기화 된 블록 내에서 캡슐화되어야합니다.


Oracle 문서 읽기

"반복 할 때 사용자가 반환 된 목록에서 수동으로 동기화해야합니다."


다른 사람들이 언급 한 것처럼 동기화 된 컬렉션은 스레드로부터 안전 하지만 이러한 컬렉션에 대한 복합 작업은 기본적으로 스레드로부터 안전하다고 보장되지 않습니다.

JCIP에 따르면 일반적인 복합 작업은 다음과 같습니다.

  • 되풀이
  • 항해
  • 부재시
  • 확인 후 행동

OP의 동기화 된 코드 블록은 복합 동작이 아니므로 추가 여부에 관계없이 차이가 없습니다.

JCIP에서 예제를 가져 와서 잠금으로 복합 동작을 보호해야하는 이유를 명확히하기 위해 약간 수정 해 보겠습니다.

list래핑 된 동일한 컬렉션에서 작동하는 두 가지 메서드가 있습니다.Collections.synchronizedList

public Object getLast(List<String> list){
    int lastIndex = list.size() - 1;
    return list.get(lastIndex);
}

public void deleteLast(List<String> list){
    int lastIndex = list.size() - 1;
    list.remove(lastIndex);
}

방법 경우 getLast와는 deleteLast두 개의 서로 다른 스레드에서 동시에 호출, 인터리빙 발생할 수 있습니다 아래에 getLast발생합니다 ArrayIndexOutOfBoundsException. 전류 lastIndex가 10 이라고 가정합니다 .

스레드 A (deleteLast)->
스레드 B 제거 (getLast) --------------------> get

Thread A removegetThread B 에서 작업 전 요소입니다 . 따라서 Thread B는 여전히 10 lastIndex을 호출하는 list.get메서드 로 사용 하므로 동시 문제가 발생합니다.

참고URL : https://stackoverflow.com/questions/9468187/collections-synchronizedlist-and-synchronized

반응형