从不同的线程访问属性

问题描述:

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

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

@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不需要同步读取和写入,因为它们是通过值....?

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

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

虽然你可以使用原子,但在实际情况下它并没有太大的帮助。他们让你的程序更多线程抵抗(不安全)在执行成本(都是坏的,顺便说一句)。

顺便说一句,通过价值在这里真的不是一个问题。

突变一个可变值或对象(例如读取,并从两个线程从该写入的NSMutableArray),和维持依赖于彼此是主要的问题实例变量的完整性。

说你是int型的(日,月)的两个原子性质,他们有访问器:维护两个实例变量依赖于彼此的诚信

例子。如果读取和写入发生在不同的线程中,您需要的不仅仅是原子数来避免读取无效日期(例如2月31日)。真正确保你的对象不在部分更新中的唯一方法是使用同步原语或不可变数据 - 这是基本的原子属性不能保存你。

所以简短的答案是'原子',但在并发的上下文中的对象很少如此简单,原子的中间地带是真正的线程安全

+0

我将在我的应用程序中使用的特定示例是,我有一个线程写入和一个线程读取的浮点数。这听起来像是我最好的选择是在这种情况下让它成为原子,而不用担心同步它。在我的例子中,写入线程是一个后台线程,它会在更新的过程密集型任务的进度百分比,而读线程是主线程,将更新与完成的百分比加载酒吧。 – MikeS 2012-08-10 18:18:04

+0

@MikeS如果它只是一个原子'float'财产,也没有依赖性或副作用的特性改变,那么“是”,这将确保您的读取/写入'通过存取方法float'从没部分书面的国家。原子工作适合这个简单的情况。这将适用于任何POD或合成的原子访问器(它也为您执行保留/自动释放周期)。这是关于他们的效用的程度,我发现。 – justin 2012-08-10 18:24:18