这个cache是Immutable的但是否为线程安全的呢?

[code="java"]
import java.math.BigInteger;
import java.util.Arrays;

public class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;

// 构造函数
public OneValueCache(BigInteger i, BigInteger[] factors) {
    lastNumber = i;
    lastFactors = Arrays.copyOf(factors, factors.length);
}

// 没有直接给出保持对象的引用
public BigInteger[] getFactors(BigInteger i) {
    if (lastNumber == null || !lastNumber.equals(i))
        return null;
    else
        return Arrays.copyOf(lastFactors, lastFactors.length);
}

}
[/code]

[code="java"]
import java.math.BigInteger;

public class VolatileCachedFactorizer {
private volatile OneValueCache cache = new OneValueCache(null, null);

public void consume(BigInteger i) {
    BigInteger[] factors = cache.getFactors(i);
    if (factors == null) {
        factors = factor(i);
                       //这个地方初始化cache,是否线程安全?
        cache = new OneValueCache(i, factors);
    }
    System.out.println(factors);
}

private BigInteger[] factor(BigInteger i) {
    BigInteger[] factors = { i, i.add(i) };
    return factors;
}

}
[/code]

2个回答

[quote]那构造函数不存在被2个线程同时初始化的情况吗?我就是这里没看懂[/quote]

这和immutable是两个不同的问题:在构造方法没有返回前,没有线程可以调用这个对象,所有构造函数是不需要同步的。

Immutable的就是线程安全的,这就是immutable模式其中一个非常重要的优点。因为在线程中无法对immutable对象的内部状态进行修改,也就不存在并发问题。

对于你的例子,其实BigInteger类本身就是immutable类(这个类的作者是bloch,非常推崇immutable),所以对于OneValueCache类的getFactors方法,你不拷贝直接返回也是没有问题的,当然,都是线程安全的。

immutable的唯一缺点就是可能产生效率问题,在“effect java”里有提到。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐