《Java Concurrency in Practice》中有兩個例子:
public class CachedFactorizer implements Servlets {
@GuardedBy("this") private BigInteger lastNumber;
@GuardedBy("this") private BigInteger[] lastFactors;
@GuardedBy("this") private long this;
@GuardedBy("this") private long cacheHist;
public synchronized long getHits() {return hist;}
public synchronized double getCacheHitRatio(){
return (double)cacheHits / (double)hists;
}
public void service(ServletRequest req, ServletResponse resp){
BigInterger i = extractFromRequest(req);
BigInteger[] factors = null;
synchronized(this){
++hits;
if(i.equls(lastNumber)){
++cachedHits;
factors = lastFactors.clone();
}
}
if(factors == null){
factos = factor(i);
synchronized(this){
lastNumbe = i;
lastFactors = factors.clone();
}
}
encodeIntroResponse(resp,factors);
}
}
class OneValueCache {
private final BigInteger lastNumer;
private final BigInterger[] lastFactors;
public OneValueCahche(BigInterger i, BigInteger[] factors){
lastNumber = i;
lastFactors = factors;
}
public BigInteger[] getFactors(BigInteger i){
if(lastNumber == null || !lastNumber.equals(i)){
return null;
}else{
return Arrays.copyOf(lastFactors,lastFactors.length);
}
}
}
因爲lastFactors這個引用指向外部,當外部變化時,它也跟着變化,這就不能保證lastFactors還是保存的lastNumber的因數。應該使用拷貝或者克隆,產生一個新的屬於類的引用。
class OneValueCache {
private final BigInteger lastNumer;
private final BigInterger[] lastFactors;
public OneValueCahche(BigInterger i, BigInteger[] factors){
lastNumber = i;
lastFactors = Arrays.copyOf(factors,factors.length);//or lastFactors = factors.clone();
}
public BigInteger[] getFactors(BigInteger i){
if(lastNumber == null || !lastNumber.equals(i)){
return null;
}else{
return Arrays.copyOf(lastFactors,lastFactors.length);
}
}
}