在以下代码中(从Java Concurrency in Practice第2章第2.5节, list 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);
}
}
为什么克隆
factors
,lastFactors
数组?不能简单地写成factors = lastFactors;
和lastFactors = factors;
吗?只是因为factors
是局部变量,然后将其传递给encodeIntoResponse
,可以对其进行修改吗?希望问题清楚。谢谢。
最佳答案
这称为防御性复制。数组是对象,因此
factors = lastFactors
会将lastFactos的引用赋给因子,反之亦然。因此,任何人都可以在您的控制范围之外覆盖您的状态。举个例子:
private void filterAndRemove(BigInteger[] arr);
private void encodeIntoResponse(..., BigInteger[] factors) {
filterAndRemove(factors);
}
使用我们的理论分配,filterAndRemove也将影响原始的lastFactorials。