1

나는 List을 여러 번 읽고 여러 번 쓰지만 거의 업데이트되지는 않습니다 (읽기 횟수가 50,000 배 이상 많습니다). 편집 : 사실, 배열이 목록 대신 충분한 경우이 충분합니다.비동기 동시 목록 또는 배열을 원자 적으로 바꾸는 방법

목록이 업데이트되면 단순히 다른 버전으로 바뀝니다 (add() 또는 remove() 호출이 없음).

CopyOnWriteArrayList 동기화 된 목록의 단점을 피할 수 있지만 새 값으로 목록을 설정하면 원자가 확실하지 않습니다. 나는 this 질문도 읽었다.

일부 코드를 표시합니다. 싱글 톤 스프링 빈의 속성으로 다음을 고려하십시오.

List<MyObject> myList; //the list read many times and concurrently. 

//called by many threads 
public void doStuff(){   
    for (MyObject mo : myList){ 
     //do something 
    } 
}  

//called rarely. It's synchronized to prevent concurrent updates 
//but my question is about thread-safety with regards to readers 
public synchronized void updateList(List<MyObject> newList){ // newList is a CopyOnWriteArrayList<>(); 
    myList = myNewList; //is this following statement executed atomically and thread-safe for readers? 
} 

스레드 안전 집합을 얻으려면 ReadWriteLock을 사용해야합니까?

+1

목록을 '휘발성으로 만드는 것'으로 충분할 것이라고 생각합니다. –

답변

1

ReadWriteLock의 필요성은 달성해야 할 항목에 따라 다릅니다. 참조가 원자 적으로 업데이트되도록하려면 AtomicReference (또는이 참조를 휘발성으로 표시하는 데 충분할 경우)을 사용할 수 있습니다. 그러나 업데이트 스레드가 모든 읽기 스레드가 업데이트하기 전에 이전 목록을 반복 할 때까지 기다려야한다는 것이 목표 인 경우 그때 참조가 ReadWriteLock가는 길입니다.

+0

독자가 끝내기를 기다리는 것이 좋은 지적입니다. 내 경우에는 목록이 짧아서 (<10 개 항목) 예상되는 부하로 모든 반복 작업이 완료되고 "조용합니다"라는 순간이 있습니다. 이것은 목록이 충분히 길고 새로운 독자가 반복하는 동안 도착률이 충분히 높으면 다른 사람이 끝내는 동안 무엇을해야하는지에 대한 흥미로운 질문을 제기합니다. 그래서 적어도 하나 이상의 반복이 계속됩니다. – wishihadabettername

+0

쓴대로 유스 케이스에 따라 다릅니다. 일부 스레드가 오래된 목록을 반복하고 휘발성이있는 경우 괜찮 으면, 여러 번 사용하는 경우를 한 번 업데이트하면 아무도 기존 목록을 사용하지 않도록 할 수 있습니다. – enterbios