UFO ET IT

자바 동기화 목록

ufoet 2020. 11. 24. 20:40
반응형

자바 동기화 목록


미리 채워진 배열 목록이 있습니다. 그리고 배열 목록에서 요소를 제거하는 여러 스레드가 있습니다. 각 스레드는 아래의 remove 메서드를 호출하고 목록에서 하나의 항목을 제거합니다. 다음 코드는 일관된 동작을 제공합니까?

ArrayList<String> list = Collections.synchronizedList(new ArrayList<String>());

void remove(String item)
{
     do something; (doesn't work on the list)
     list.remove(item);
}

감사!


예, 목록을 반복하는 경우에도주의해야합니다.이 경우 동기화해야하기 때문입니다. 로부터 자바 독 :

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

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

또는 CopyOnWriteArrayList쓰기 속도가 더 느리지 만이 문제가없는 것을 사용할 수 있습니다 .


"remove"메서드가 원자적일 필요가없는 한 괜찮습니다.

즉, "무언가"가 항목이 목록에 두 번 이상 나타나는지 확인하는 경우 다음 줄에 도달 할 때 해당 확인 결과가 잘못 될 수 있습니다.

또한 반복 할 때 목록에서 동기화해야합니다.

synchronized(list) {
    for (Object o : list) {}
}

Peter Lawrey가 언급했듯이 CopyOnWriteArrayList 는 사용자의 삶을 더 쉽게 만들고 동시성이 높은 환경에서 더 나은 성능을 제공 할 수 있습니다.


에서 Collections#synchronizedList(List)의 javadoc

지정된 목록에서 지원하는 동기화 된 (스레드 안전) 목록을 반환합니다. 직렬 액세스를 보장 하려면 백업 목록에 대한 모든 액세스가 반환 된 목록을 통해 수행되는 것이 중요합니다. 사용자가 반환 된 목록을 반복 할 때 반환 된 목록에서 수동으로 동기화해야합니다. 이 조언을 따르지 않으면 비 결정적 동작이 발생할 수 있습니다.


목록에는 두 가지 다른 문제가있을 수 있습니다.
1) 모노 스레드 환경에서도 반복 내에서 수정을 수행하면 다음 예제와 같이 ConcurrentModificationException이 발생합니다.

List<String> list = new ArrayList<String>();
for (int i=0;i<5;i++)
   list.add("Hello "+i);

for(String msg:list)
   list.remove(msg);

따라서이 문제를 방지하려면 다음을 수행 할 수 있습니다.

for(int i=list.size()-1;i>=0;i--)
   list.remove(i);

2) 두 번째 문제는 다중 스레딩 환경 일 수 있습니다. 위에서 언급했듯이 동기화 (list)를 사용하여 예외를 피할 수 있습니다.


추가 / 제거 작업에 대해 일관된 동작을 제공합니다. 그러나 반복하는 동안 명시 적으로 동기화해야합니다. 이 링크 참조


예, synchronized목록 있으므로 잘 작동 합니다. 을 사용하는 것이 좋습니다 CopyOnWriteArrayList.

CopyOnWriteArrayList<String> cpList=new CopyOnWriteArrayList<String>(new ArrayList<String>());

    void remove(String item)
    {
         do something; (doesn't work on the list)
                 cpList..remove(item);
    }

synchronized(list) {
    for (Object o : list) {}
}

참고 URL : https://stackoverflow.com/questions/11360401/java-synchronized-list

반응형