A thread-safe holder for arbitrary cloneable data

只愿长相守 提交于 2020-01-25 07:39:06

问题


I have a class SomeMutableData with a public clone() method. I want to make sure, that no thread ever sees an inconsistent state (assuming the instances will be passed around using the holder only). I assume using synchronization is the safest possibility, right?

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;
}

Is the following as safe as the first approach?

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>();
}

回答1:


Since clone() is much more expensive than synchronized, it hardly matters from a performance point of view.

However the second example is as thread safe and marginally faster.

the only differences is that the first example you can do this. (Whether you like this or not ;)

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

BTW: I don't think the holder should extend the type it is wrapping.

EDIT: A more GC friendly way is to use the following approach. you can write copyFrom() such that no objects are created either setting or getting the data.

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);
    }
}


来源:https://stackoverflow.com/questions/5462150/a-thread-safe-holder-for-arbitrary-cloneable-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!