- 关于"线程安全"的问题是,任何东西本身都不是"线程安全"。线程安全"只能在给定的上下文中确定,其中"线程安全"意味着尽管可能有多个线程,但仍然可以确保整个上下文的正确操作。例如,可变数组的特定实现可以说是真空中的"线程安全",因为人们永远不会访问内部不一致的数据,但如果条目没有与它引用的外部数据同步维护,这就毫无意义。这种同步只能在外部进行。
原子性解决的问题
- (NSNumber *)count {
NSNumber *count;
@synchronized(self) {
count = [_count retain]; // +1
}
return [count autorelease]; // delayed -1
}
- (void)setCount:(NSNumber *)count {
id oldValue;
@synchronized(self) {
oldValue = _count;
_count = [count retain];
}
[oldValue release];
}
以上代码为设置原子性的属性的setter和getter原理差不多,线程A和线程B在设置属性时,等一条线程操作完成后,另一条线程才会执行。
非原子属性的setter方法中,线程A和线程B可能同时执行写入时,那线程A可能获取的是线程B中的oldValue或newValue,存在安全隐患。例如,两个操作都获取的是旧值,那么旧值会执行两次release,导致过度释放崩溃。
原子性不能避免的问题
多个线程同步获取整型属性并执行+1时,不同的线程可能都是得到旧值然后执行+1,那么最终的整型值不会是期望的结果。
此类风险的问题在特定上下文中会出现