1

我有两个线程访问同一组属性,但一个只读取属性,另一个只写入属性。

以下哪些属性需要同步以进行读操作,哪些必须同步以进行写操作?

@property (nonatomic) int myInt;
@property (nonatomic) NSInteger myInteger;
@property (nonatomic) CGImageRef cgImage;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) NSMutableArray *array;
@property (nonatomic, strong) UIViewController *controller;

我的第一直觉是,所有的读写操作都需要一直同步。然而,由于一个线程总是在写,一个线程总是在读,我不确定自己。当然,总是同步是“安全的”,因为我不确定,但我想知道什么是真正正确的?

出于某种原因,我有这种感觉,也许 myInt 和 myInteger 不需要同步读取和写入,因为它们是按值传递的......?

4

1 回答 1

4

嗯,这就是原子属性擅长的。如果它们都是原子的,那么你可以读写而不会得到部分写入的结果。

但是,我从未发现原子 objc 属性在并发程序中真正有用。我总是导致定期锁定、不变性等。

尽管您可以使用原子,但在实际情况下它并不能帮助您。它们以执行成本使您的程序更具线程抗性(不安全)(两者都很糟糕,顺便说一句)。

顺便说一句,按值传递在这里真的不是问题。

改变一个可变值或对象(例如,从两个线程读取和写入该 NSMutableArray),以及维护相互依赖的 ivars 的完整性是主要问题。

维护两个相互依赖的 ivars 完整性的示例:

假设您有两个 int 类型(日、月)的原子属性,并且它们具有访问器。如果读取和写入是从不同的线程发生的,那么您将需要更多的原子来避免读取无效的日期(例如 2 月 31 日)。真正确保您的对象不在部分更新中的唯一方法是使用同步原语或不可变数据——这是基础原子属性无法拯救您的。

所以简短的回答是“原子”,但并发上下文中的对象很少如此简单,以至于原子的中间立场是真正的线程安全

于 2012-08-10T18:01:40.727 回答