atomic
在objc
中是用來修飾屬性复局,表示屬性的寫操作是一個(gè)原子操作郁副。本文以幾段代碼為例珠漂,分析為什么atomic
修飾的屬性并不是線程安全的崩溪。
定義一個(gè)帶有atomic
屬性的Model
@interface Model : NSObject
@property (atomic, assign) NSInteger index;
@end
@implementation Model
@end
首先我們看下述代碼代碼一父款。輸出結(jié)果大家都知道是無序的溢谤。
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
Model *m = [Model new];
for (int i = 0; i < 100; i++) {
dispatch_async(queue, ^{
m.index++;
NSLog(@"index = %ld", m.index);
});
}
這段代碼代碼二,大家也知道結(jié)果憨攒,輸出是有序的世杀。
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
NSLock *lock = [NSLock new];
Model *m = [Model new];
for (int i = 0; i < 100; i++) {
dispatch_async(queue, ^{
[lock lock];
m.index++;
NSLog(@"index = %ld", m.index);
[lock unlock];
});
}
接下來,我們拆分一下有序的代碼肝集,代碼三瞻坝。ok,這部分也是有序的杏瞻,沒有問題所刀。
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
NSLock *lock = [NSLock new];
Model *m = [Model new];
for (int i = 0; i < 100; i++) {
dispatch_async(queue, ^{
[lock lock];
m.index++;
[lock unlock];
[lock lock];
NSLog(@"index = %ld", m.index);
[lock unlock];
});
}
調(diào)整一下代碼衙荐,代碼四:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
NSLock *lock = [NSLock new];
Model *m = [Model new];
for (int i = 0; i < 100; i++) {
dispatch_async(queue, ^{
m.index++;
[lock lock];
NSLog(@"index = %ld", m.index);
[lock unlock];
});
}
這段代碼可能就需要思考一下了。首先m.index++;
是原子的浮创,NSLog(@"index = %ld", m.index);
也是原子的忧吟,那么應(yīng)該能順序輸出。但實(shí)際運(yùn)行代碼后發(fā)現(xiàn)斩披,還是無序的瀑罗。
最后一個(gè)例子,代碼五:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
NSLock *lock1 = [NSLock new];
NSLock *lock2 = [NSLock new];
Model *m = [Model new];
for (int i = 0; i < 100; i++) {
dispatch_async(queue, ^{
[lock1 lock];
m.index++;
[lock1 unlock];
[lock2 lock];
NSLog(@"index = %ld", m.index);
[lock2 unlock];
});
}
可能已經(jīng)被繞暈了雏掠,如果單獨(dú)拿出這段代碼,大家很快就能回答出來劣像,無序的乡话。
看完這五個(gè)例子,大家應(yīng)該已經(jīng)有答案了耳奕。實(shí)際上atomic
能保證屬性的寫操作是原子的绑青,導(dǎo)致atomic
不能保證線程安全的原因是問題的規(guī)模。問題規(guī)模的擴(kuò)大屋群,導(dǎo)致鎖操作的范圍需要擴(kuò)展闸婴,而屬性的原子操作對(duì)于擴(kuò)大規(guī)模后問題的解決沒有任何幫助,所以atomic
并不能保證線程安全芍躏。