2016-12-15 4 views
-1
public class ListHelper<E> { 
    public List<E> list = 
    Collections.synchronizedList(new ArrayList<E>()); 
    ... 
    public synchronized boolean putIfAbsent(E x) { 
    boolean absent = !list.contains(x); 
    if (absent) 
    list.add(x); 
    return absent; 
    } 
} 

이것이 작동하지 않는 이유를 이해할 수 없습니다.왜 잠금이 잘못 되었습니까?

목록을 비공개 필드로 변경하면이 코드가 올바르지 않습니까?

+0

나는 당신이 거기에서 무엇을 얻고 싶은지 전혀 알지 못한다. 왜 그런지는 모르겠지만, 당신은'Set'을 무시하고'List'를 통해 그것을 사용하고 싶어 할 것 같다. – SomeJavaGuy

답변

1

synchronized 잠금을 우회하여 다른 코드가 list에 직접 액세스 할 수 있기 때문에 코드가 작동하지 않습니다 (즉, 액세스가 안정적으로 동기화되지 않음).

private으로 설정하면이를 방지 할 수 있습니다.

synchronizedList을 사용하고 있다는 사실은 도움이되지 않습니다 (동기화 잠금이 해당 메서드에서 사용하는 것과 동일하지만 그렇지 않은 경우 유용합니다).

list을 공개하려면 동일한 잠금 (예 : list)에서 동기화되도록 메소드를 업데이트 할 수 있습니다.

이 접근법은 detailed in the JavaDoc for synchronizedList입니다.

관련 문제