2012-03-19 2 views
2

가 다른 객체 B

개체입니다 목록 을 포함

객체 A가 그것의 내부 목록을 가진 개체 A를 공유하는 2 개 이상의 스레드가 말 오브젝트 객체 B

이제 스레드가

질문은 읽기/개체 B, 수정 무엇을 동기화해야 하는가? 개체 A는 둘 다 액세스하므로 개체 B는 읽기/수정이므로

어디서나 내 질문에 대한 답변을 찾을 수 없습니다. 사전

답변

0

에서

덕분에 당신은 당신이 그 방법 (또는 서면 않는 부분) 동기화를해야한다, 그 방법 중 하나를 통해 객체 B를 수정합니다.

2

가장 간단하고 안전한 경로로 이동하려면 원자 계층 방식으로 작동해야하는 개체 계층 구조의 가장 바깥 쪽 개체를 동기화해야합니다.

예를 들어 목록에서 (필자는 실제 코드없이 실제로 무엇을 할 것인지 확신 할 수 없음)을 동기화해야하는 것처럼 보입니다.

class B { 
} 

class A { 
    private final List<B> listOfBs = new ArrayList<B>(); 

    void add(B b) { 
     synchronized (listOfBs) { 
      listOfBs.add(b); 
     } 
    } 

    List<B> getSnapshot() { 
     List<B> copy = new ArrayList<B>(); 
     synchronized (listOfBs) { 
      copy.addAll(listOfBs); 
     } 
     return copy; 
    } 
} 

하십시오, 참고 일부 코드는 자성 위반 목록을 참조를 변경할 수 있다는 가능성을 제거하기 위해 final으로 목록을 선언해야합니다 :

// will make add() and getSnapshot() not mutually exclusive, thus violating atomicity of operations 
    ... 
    listOfBs = new ArrayList<B>(); 
    ... 

읽기 여기

샘플 코드입니다 Java concurrent programming tutorial 도움이 될 것입니다.

+0

이 코드는 수정 불가능한 래퍼로 listOfBs를 래핑하면 getSnapshot()의 결과가 스레드로부터 안전 해지지 않으므로 스레드 안전성이 보장되지 않습니다. (add()를 호출 한 호출 측은, 변경 불가능한 래퍼에 의해 참조되고있는 listOfB를 변경할 수 있기 때문에). 이 코드를 쓰레드에 안전하게 만들려면, 래핑하기 전에 목록에 _copy_와 같은 것을하거나 쓰레드에 안전한 컬렉션 구현을 사용해야한다. – jtahlborn

+0

@jtahlborn, 고맙습니다. –

+0

'getSnapshot()'에서'copy.addAll (listOfBs);'만이 synchronized 블록에 있어야합니다. 동기화 범위를 제한하는 것이 가장 좋습니다. –