这个意思是说,当一个对象抛出异常之后,我们总是期望这个对象仍然保持一种定义良好的可用状态,对于被检查异常而又为中恢复出来。
所以,一般而言,一个失败的方法调用应该使对象保持“它被调用之前的状态”。这个是失败原子性。
对于非可变对象是肯定没有关系的,他们的值和域都是会保持不变的。
对于可变对象要获得原子性失败的方法就是在执行操作之前做参数的有效性检查,这可以使得对象的状态被改变以前,适当的异常就已经得到抛出。
public Object pop(){
if(size==0){
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size]=null;
return result;
}
如果在对大小进行检查不做判断的话,当一个方法调用POP的时候,如果是空栈,就会抛出异常。
这样最大的后果就是让这个对象的值域size从空栈的0,变成-1。这样导致了该对象可我们要做的就是防止这样的事情发生。
这样的做法对于计算是很有用的,可以使得计算部分都发生在对象状态被修改之前。
第3种恢复的办法,不是被迫检查而是,在失败以后做恢复代码。让他在解释操作过程中发生的失败,以及使对象回滚到操作开始之前的状态上。这个做法一般是数据库事务就是这么做的。
最后一种恢复做法,是利用对象的值的临时拷贝执行操作。就是当操作完成之后,再把临时拷贝中的结果复制给原来对象。这个方法其实很常用,例如,Collection.sort方法,在执行派讯之前,首先把它的输入列表转存到一个数组中,以便降低在排序的内循环中访问元素所这个虽然是基于性能上的原因才这么做的,但是作为另外件原来的样子。需要的开销。
以上做法都是相当经典的方法,这些方法学值得我们去学习。
但是我们也不能都做到原子性失败,比如,两个线程企图在没有适当同步机制的情况下,并发修改同一个对象,那么对象就可能在不一致的状态中。因此,在捕获一个ConcurrentModificationException异常之后再去假设对象仍然可用,这个是不正确的。
努力使失败保持原子性
最新推荐文章于 2023-09-22 18:24:03 发布
