atomic
@property (atomic,assign) int age;
意味著這個(gè)屬性是原子性操作,也就是保證setter
和gette
r是線程同步的.
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
if (offset == 0) {
object_setClass(self, newValue);
return;
}
id oldValue;
id *slot = (id*) ((char*)self + offset);
if (copy) {
newValue = [newValue copyWithZone:nil];
} else if (mutableCopy) {
newValue = [newValue mutableCopyWithZone:nil];
} else {
if (*slot == newValue) return;
newValue = objc_retain(newValue);
}
if (!atomic) {
oldValue = *slot;
*slot = newValue;
} else {
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
oldValue = *slot;
*slot = newValue;
slotlock.unlock();
}
objc_release(oldValue);
}
源碼上來看如果是atomic
,賦值的前后加了自旋鎖spinlock
它并不能保證使用屬性的過程是線程安全的.
MyPerson *person = [MyPerson new];
person.datas = [NSMutableArray new];
//如果這邊不加鎖,多線程情況下并不能保證線程同步.atomic僅保證了getter方法的線程同步.addObject方法不是線程同步
//加鎖
[person.datas addObject:@"1"];
[person.datas addObject:@"2"];
[person.datas addObject:@"3"];
//解鎖
IO操作
讀寫安全方案
- 同一時(shí)間.只能有一個(gè)線程進(jìn)行寫的操作
- 同一時(shí)間,允許有多個(gè)線程進(jìn)行讀的操作
- 同一時(shí)間,不允許既有寫的操作又有讀的操作
pthread_rwlock
:讀寫鎖
dispatch_barrier_async
異步柵欄調(diào)用
@interface ViewController ()
@property (nonatomic,assign) pthread_rwlock_t lock;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
pthread_rwlock_init(&_lock, NULL);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
[self read];
});
dispatch_async(queue, ^{
[self write];
});
}
}
- (void)read
{
pthread_rwlock_rdlock(&_lock);
sleep(1);
NSLog(@"%s",__func__);
pthread_rwlock_unlock(&_lock);
}
- (void)write
{
pthread_rwlock_wrlock(&_lock);
sleep(1);
NSLog(@"%s",__func__);
pthread_rwlock_unlock(&_lock);
}
@end
dispatch_barrier_sync
- 這個(gè)函數(shù)傳入的并發(fā)隊(duì)列必須是通過
dispatch_queue_create
創(chuàng)建的. - 如果傳入的是個(gè)串行or全局的并發(fā)隊(duì)列,效果等同于
dispatch_async
dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 50; i++) {
dispatch_async(queue2, ^{
[self read];
});
dispatch_async(queue2, ^{
[self read];
});
dispatch_async(queue2, ^{
[self read];
});
dispatch_barrier_sync(queue2, ^{
[self write];
});
}
- (void)read
{
// pthread_rwlock_rdlock(&_lock);
sleep(1);
NSLog(@"%s",__func__);
// pthread_rwlock_unlock(&_lock);
}
- (void)write
{
// pthread_rwlock_wrlock(&_lock);
sleep(1);
NSLog(@"%s",__func__);
// pthread_rwlock_unlock(&_lock);
}