美文网首页
atomic是否线程安全?

atomic是否线程安全?

作者: minking1982 | 来源:发表于2017-07-16 21:51 被阅读0次

    在申明属性的时候默认的是atomic原子性,在使用属性时我们会手动设置noatomic表示非原子性,这样做以提高访问效率,不过多线程访问属性时数据是不安全的。那么atomic原子性是否就可以保证线程安全了呢?

    这个需要分两种情况来讲

    • 对于int,float之类的属性,使用atomic能够保证数据线程安全,atomic的这类属性可以保证线程访问时的顺序执行。

    • 对于NS类型的数据,使用atomic却并不一定可以保证其线程安全。

    要理解这个问题先要讲述一下属性合成。
    noatomic属性合成时如下

    对于一般数据类型的合成
    -(void)setNumber:(int) number
    {
        _number = number;
    }
     -(int) number
    {
      return number;
    }
    
    对于NSString或者NSArray的合成
    @property(nonatomic,copy)NSString* str;
    
    -(void)setStr:(NSString*)str
    {
      _str = [str copy];
    }
    -(NSString*)str
    {
      return str;
    }
    

    atomic属性合成

    对于一般数据类型的合成
    -(void)setNumber:(int) number
    {
      @synchronized(self)
      {
      self.number = number;
      }
    }
     -(int) number
    {
      @synchronized(self)
      {
        return number;
      } 
    }
    
    对于NSString或者NSArray的合成
    @property(atomic,copy)NSString* str;
    
    -(void)setStr:(NSString*)str
    {
      @synchronized(self)
      {
        _str = [str copy];
      }
    }
    -(NSString*)str
    {
      @synchronized(self)
      {
        return str;
      }
    }
    

    由此可见atmoic只针对于setter和getter方法,所以对于基础数据类型如int等,其可以保证数据的线程安全。 在上例中的@property(atomic,copy) NSString* str;同样也是线程安全的。因为对str的操作都有@synchronized(self)保证同步。

    但是对于@property(atomic,strong) NSMutableString* str; 这样的属性,如果仅仅对于str的读取和赋值,atomic同样也能保证线程顺序执行。但是由于NSMutableString是可变类型,对于可变类型对应的add,insert,remove等方法是对于指针所指向内存区域的操作,而atomic无法保证指针所指向区域的线程访问安全,然而对于这类数据类型,这种操作是很常见的。

    由上分析得出以下结论

    • atomic原子性,它仅限于getter,setter时的线程安全
    • 因为atomic原子性,它限于getter,setter时的线程安全,所以对于一般数据类型如int,float它是可以保证线程安全的,对于NSString这种不可变字符串也能保证线程安全。
    • 对于NSMutable类型的属性,atmoic无法保证线程安全,对于这种属性往往都是对于数据块的读写操作,atmoic无法保证对于指针指向的数据库的线程安全。这种属性时使用nonatomic,自己处理线程安全。
    • 同样的对于NSMutable开头的一些类,使用atmoic还是会导致线程问题的

    相关文章

      网友评论

          本文标题:atomic是否线程安全?

          本文链接:https://www.haomeiwen.com/subject/gzjxkxtx.html