本文介绍了任意可克隆数据的线程安全持有者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有公共 clone() 方法的 SomeMutableData 类.我想确保没有线程看到不一致的状态(假设实例将仅使用持有者传递).我认为使用同步是最安全的可能,对吗?

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

推荐答案

由于 clone() 比 synchronized 昂贵得多,因此从性能的角度来看,它几乎无关紧要.

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.

更友好的 GC 方法是使用以下方法.您可以编写 copyFrom() 以便不创建设置或获取数据的对象.

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

这篇关于任意可克隆数据的线程安全持有者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:53