2011-03-28 4 views
0

나는 clone() 공개 메서드가있는 SomeMutableData 클래스가 있습니다. 나는 어떤 스레드도 일관성없는 상태를 보지 못하도록하고 싶다. (인스턴스가 홀더만을 사용하여 전달된다고 가정 할 때). 동기화를 사용하는 것이 가장 안전한 방법이라고 생각합니다. 맞습니까?임의의 복제 가능 데이터를위한 스레드 안전 홀더

public final class ThreadSafeHolder { 
    public ThreadSafeHolder(SomeMutableData data) { 
     storeData(data); 
    } 

    public synchronized SomeMutableData cloneData() { 
     return data.clone(); 
    } 
    public synchronized void storeData(SomeMutableData data) { 
     this.data = data.clone(); 
    } 

    private SomeMutableData data; 
} 

첫 번째 접근 방식은 다음과 같이 안전합니까?

public final class ThreadSafeHolder2 { 
    public ThreadSafeHolder2(SomeMutableData data) { 
     storeData(data); 
    } 

    public SomeMutableData cloneData() { 
     return data.get().clone(); 
    } 
    public void storeData(SomeMutableData data) { 
     this.data.set(data.clone()); 
    } 

    private final AtomicReference<SomeMutableData> data 
     = new AtomicReference<SomeMutableData>(); 
} 

답변

2

clone()은 동기화 된 것보다 훨씬 비쌉니다. 성능 측면에서 보면별로 중요하지 않습니다.

그러나 두 번째 예제는 스레드 안전성과 속도면에서 약간 빠릅니다.

유일한 차이점은 첫 번째 예를 들어 볼 수 있다는 것입니다. (이 여부를 좋아하든) BTW

synchronized(theHolder) { 
    SomeMutableData smd = theHolder.cloneData(); 
    smd.updateIt(); 
    theHolder.storeData(smd); 
} 

: 나는 홀더가 포장 된 유형을 확장해야한다고 생각하지 않습니다.

편집 : 더 GC 친화적 인 방법은 다음 접근 방식을 사용하는 것입니다. copyFrom()을 작성하여 데이터를 설정하거나 가져 오는 오브젝트가 작성되지 않도록 할 수 있습니다.

public final class ThreadSafeHolder { 
    private final SomeMutableData data = new SomeMutableData(); 

    public ThreadSafeHolder(SomeMutableData data) { 
     copyFrom(data); 
    } 

    public synchronized void copyTo(SomeMutableData data) { 
     data.copyFrom(this.data); 
    } 

    public synchronized void copyFrom(SomeMutableData data) { 
     this.data.copyFrom(data); 
    } 
} 
+1

* "홀더가 포장하는 유형을 확장해야한다고 생각하지 않습니다."* - 나도! 나 아니야, 일식이야 ... – maaartinus