iOS|iOS 属性修饰符atomic的内部实现是怎么样的?能保证线程安全吗()
iOS 属性修饰符atomic的内部实现是怎么样的?能保证线程安全吗?
1、内部实现
【iOS|iOS 属性修饰符atomic的内部实现是怎么样的?能保证线程安全吗()】在 objc4-723 的 Objective-C runtime 实现中,property 的 atomic 是采用 spinlock_t 也就是俗称的自旋锁实现的。
// getter
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic)
{
// ...
if (!atomic) return *slot;
// Atomic retain release world
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
id value = https://www.it610.com/article/objc_retain(*slot);
slotlock.unlock();
// ...
}
// setter
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
// ...
if (!atomic)
{
oldValue = https://www.it610.com/article/*slot;
*slot = newValue;
}
else
{
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
oldValue = *slot;
*slot = newValue;
slotlock.unlock();
}
// ...
}
2、能否保证线程安全? atomic通过这种方法,在运行时保证 set,get方法的原子性。
仅仅是保证了set,get方法的原子性。
这种线程是不安全的。
@property (atomic, assign)intintA;
//线程A
for (int i = 0;
i < 10000;
i ++)
{
self.intA = self.intA + 1;
NSLog(@"Thread A: %d\n", self.intA);
}//线程B
for (int i = 0;
i < 10000;
i ++)
{
self.intA = self.intA + 1;
NSLog(@"Thread B: %d\n", self.intA);
}
self.intA 是原子操作,但是self.intA = self.intA + 1这个表达式并不是原子操作。
所以线程是不安全的。
threadA 在执行表达式 self.intA之后 self.intA = self.intA + 1; 并没有执行完毕
此时threadB 执行self.intA = self.intA + 1;
再回到threadA时,self.intA的数值就被更新了
所以仅仅使用atomic并不能保证线程安全。
推荐阅读
- 第6.2章(设置属性)
- 2020-04-07vue中Axios的封装和API接口的管理
- iOS中的Block
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- 7、前端--jQuery简介、基本选择器、基本筛选器、属性选择器、表单选择器、筛选器方法、节点操作、绑定事件
- 接口|axios接口报错-参数类型错误解决
- iOS|iOS 笔记之_时间戳 + DES 加密