线程安全中的不变性(Invariant)

多线程环境下,如果一个类的几个变量之间存在不变性(Invariant),需要使用同步确保不变性不会被破坏。不变性是几个变量之间的逻辑关系(logical assertion),不管按照什么顺序,不管哪个线程操作后,这个关系要保持不变,否则程序就会出错。

在<<Java Concurrency in Practice>>举了一个例子。一个类设计来求解一个整数的因式分解,多个线程会访问这个类,为了提高响应,存放了最近的整数和因素分解的结果。


class CachedFactorizer{
    private int lastNumber;
    private []Integer lastFactors;


    public Integer[] factorizeInt(int number ){
        Integer[] factors = null;
        synchronized(this){
            if(number == lastNumber){
               //must clone. if just use factors = lastFactors, it is possible that some thread change lastFactors before return factors.
                factors = lastFactors.clone();                     
            }
        }
        if(factors == null){
            factors = factorize(number);
            synchronized(this){      
                lastNumber = number;
                //must clone. factors is a auto variable, it is possible to be released after end calling the function.
                //lastFactors could refer to a invalid space.
                lastFactors = factors.clone();                                              
            }
        }
        return factors;        
    }


    public static Integer[] factorize(int number){
      Integer [] factors=null;
 if(number>1){
   ArrayList<Integer> result = new ArrayList<Integer>();
   for(int i=2;i<number;i++){
 while(number != i){
   if(number%i != 0){
     break;
   }
   result.add(i);
   number = number/i;
 }
}
result.add(number);
result.toArray((factors=new Integer[result.size()]));
}
return factors;
    }
}


变量lastNumber和lastFactors之间就存在明显的不变性,就是:lastFactors存放的数确实是lastNumber的因素。如果没有正确使用同步,lastNumber已经修改,而lastFactors却没有修改,那么它们之间的不变性就被破坏了。多个变量存在不变性时,就需要在单个原子操作中更新所以相关的状态变量。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值