今天看到了一个例子:功能:在不可变的容器中缓存数字和它的因数
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都是不可更改引用的啊.为什么书中说“如果更新变量,会创建新的容器对象”呢????这句话怎么理解???

解决方案 »

  1.   

    构造方法都是操作当前对象的成员变量吧。。俩线程分别new自己的对象不影响的吧。。lastNumber和lastFactors都是final的话,getFactors用一下也应该没问题。。你觉得捏?我不是很确定爱。。
      

  2.   

    “如果更新变量,会创建新的容器对象”我估计他是不是想说改getFactors的返回值?Arrays.copyOf方法貌似是复制一份数据返回给客户端代码,就没有并发的事情了。