@synchronized的正确使用方式是什么?

9
@property (atomic, retain) NSArray *array;

我不会覆盖数组的setter和getter方法。我可以使用@synchronized(array){}或@synchronized(self.array){}。据我所知,这两种情况都是正确的,我对吗?

2个回答

12

使用@syncrhonized(obj)只是形成一个锁,以便在同一时间内不会执行在obj上同步的其他代码。

原子性属性通过不允许在访问属性时进行更改来工作;它们提供了对访问的隐式锁定。

array = someObject.array; //locked
[array doSomething];      //no longer locked

您无法覆盖 atomic 属性的 getter 和 setter 方法,但是在 getter/setter 周围使用 @synchronized 指令应该足够了。

@synthesize array=_array;

...

-(void)setArray
{
    @synchronized(self) 
    {
        _array = array;
    }
}

-(NSArray *)array
{
    NSArray *retVal;

    @synchronized(self) 
    {
        retVal = _array;
    }

    return retVal;
}

说实话,除非你正在进行一些严重的多线程编程,否则原子属性是不必要的,只会导致性能下降。


1
显然,使用@synchronized的getter和setter示例与线程安全相去甚远,因此几乎从不应用此模式。通常需要在更高层次上执行同步以实现线程安全。 - Rob

9

根据您的提问方式,从并发安全策略的角度来看,两种陈述是等效的。

根据项目规模和完成工作的程度,您可能希望考虑完全替代线程安全的另一种策略。

最近,苹果公司强烈推荐通过序列化实现线程安全,而不是传统的阻塞方式。简而言之,随着争用程度的增加,序列化访问比@synchronize阻塞更有效率。

请考虑设置GCD串行队列,并将对跨线程共享资源的访问排队。


1
或者更好的是,使用读写者模式和GCD并发队列,在读取操作中使用dispatch_sync,在写入操作中使用dispatch_barrier_async - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接