今天看到了一个例子:功能:在不可变的容器中缓存数字和它的因数
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);
}
}书上对这段代码的解释:
通过使用不可变对象持有所有的变量,可以取消在访问和更新这些变量时的竞争条件。若使用可变的容器对象,你就必须使用锁以确保原子性;使用不可变对象,一旦一个线程获得它的引用,永远不必担心其他线程会修改它的状态。(我对这段的理解是没有问题的),但是后面这段(如果更新变量,会创建新的容器对象),不过在次之前任何线程都还和原先的容器打交道,仍然看到它处于一致的状态。
首先按我的理解,lastNumber和lastFactors都是不可改变引用的对象,那么如果第一个线程调用OneValueCache方法时,很自然可以进行,把lastNumber指向了BigInteger i,lastFactors指向了factors,但是如果这时有第二个线程进入了OneValueCache方法,这时不会报错么?lastNumber和lastFactors都是不可更改引用的啊.为什么书中说“如果更新变量,会创建新的容器对象”呢????这句话怎么理解???
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);
}
}书上对这段代码的解释:
通过使用不可变对象持有所有的变量,可以取消在访问和更新这些变量时的竞争条件。若使用可变的容器对象,你就必须使用锁以确保原子性;使用不可变对象,一旦一个线程获得它的引用,永远不必担心其他线程会修改它的状态。(我对这段的理解是没有问题的),但是后面这段(如果更新变量,会创建新的容器对象),不过在次之前任何线程都还和原先的容器打交道,仍然看到它处于一致的状态。
首先按我的理解,lastNumber和lastFactors都是不可改变引用的对象,那么如果第一个线程调用OneValueCache方法时,很自然可以进行,把lastNumber指向了BigInteger i,lastFactors指向了factors,但是如果这时有第二个线程进入了OneValueCache方法,这时不会报错么?lastNumber和lastFactors都是不可更改引用的啊.为什么书中说“如果更新变量,会创建新的容器对象”呢????这句话怎么理解???
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货