atomic:原子属性,多线程写入属性时,保证同一时间只有一个线程能够写入操作,单线程写,多线程读的操作,读写相对安全的
atomic 内部有一把锁:自旋锁
自旋锁:如果发现其他线程正在执行锁定的代码。线程就会出现死循环,等待线程完成就执行锁定代码
开发中经常使用 nonatomic 修饰属性,原因是因为:锁的开销比较大,容易造成性能问题。nonatomic 是线程不安全的,但是atomic 也不是绝对的安全,只是能降低不安全的概率。
在默认情况下,由编译器所合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备 nonatomic 特质,则不使用互斥锁(atomic 的底层实现,老版本是自旋锁,iOS10开始是互斥锁--spinlock底层实现改变了。)。请注意,尽管没有名为“atomic”的特质(如果某属性不具备 nonatomic 特质,那它就是“原子的”(atomic))。
在iOS开发中,你会发现,几乎所有属性都声明为 nonatomic。
一般情况下并不要求属性必须是“原子的”,因为这并不能保证“线程安全” ( thread safety),若要实现“线程安全”的操作,还需采用更为深层的加锁机制才行。例如,一个线程在连续多次读取某属性值的过程中有别的线程在同时改写该值,那么即便将属性声明为 atomic,也还是会读到不同的属性值。
因此,开发iOS程序时一般都会使用 nonatomic 属性。但是在开发 Mac OS X 程序时,使用 atomic 属性通常都不会有性能瓶颈。
- (void)setMyAtomic(UIImage *)MyAtomic
{
if (_MyAtomic != MyAtomic) {
[_MyAtomic release];
_MyAtomic = [MyAtomic retain];
// do something
}
}
- (UIImage *)MyAtomic
{
return _MyAtomic;
}
atomic的实现:
- (void)setMyAtomic:(UIImage *)MyAtomic
{
@synchronized(self) {
if (_MyAtomic != MyAtomice) {
[MyAtomic release];
_MyAtomic = [MyAtomic retain];
// do something
}
}
}
- (UIImage *)MyAtomic
{
@synchronized(self) {
return _MyAtomic;
}
}
- (void)myMethod:(id)anObj
{
@synchronized(anObj)
{
}
}