"实践中的Java并发" - 缓存的线程安全数字因子(清单2.8)

kha*_*hik 7 java clone local-variables thread-safety

在下面的代码中(从Java Concurrency in Practice第2章,第2.5节,清单2.8中复制):

@ThreadSafe
public class CachedFactorizer implements Servlet {
    @GuardedBy("this") private BigInteger lastNumber;
    @GuardedBy("this") private BigInteger[] lastFactors;
    @GuardedBy("this") private long hits;
    @GuardedBy("this") private long cacheHits;

    public synchronized long getHits() { return hits; }

    public synchronized double getCacheHitRatio() {
        return (double) cacheHits / (double) hits;
    }

    public void service(ServletRequest req, ServletResponse resp) {
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = null;
        synchronized (this) {
            ++hits;
            if (i.equals(lastNumber)) {
                ++cacheHits;
                factors = lastFactors.clone(); // questionable line here
            }
        }
        if (factors == null) {
            factors = factor(i);
            synchronized (this) {
                lastNumber = i;
                lastFactors = factors.clone(); // and here
            }
        }
        encodeIntoResponse(resp, factors);
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么factors,lastFactors数组被克隆?难道不能简单地写成factors = lastFactors;lastFactors = factors;?只是因为它factors是一个局部变量然后传递给encodeIntoResponse它,可以修改它吗?

希望问题很清楚.谢谢.

小智 0

从基础上猜测的答案:如果您打算修改对象,并且不想修改原始对象,则需要克隆,在您的情况下factors = lastFactors.clone();已经完成,因为您不想lastFactors被修改,而是克隆它并将其发送encodeIntoResponse(resp, factors);到可能包含修改它的代码。