@synchronized
結(jié)構(gòu)所做的事情跟鎖lock
類似:它防止不同的線程同時執(zhí)行同一段代碼峰档。但在某些情況下视卢,相比于使用 NSLock
創(chuàng)建鎖對象纠炮、加鎖和解鎖來說今豆,@synchronized
用著更方便,可讀性更高颜骤。
@synchronized
的例子
@implementation ThreadSafeQueue
{
NSMutableArray *_elements;
NSLock *_lock;
}
- (instancetype)init
{
self = [super init];
if (self) {
_elements = [NSMutableArray array];
_lock = [[NSLock alloc] init];
}
return self;
}
- (void)push:(id)element
{
[_lock lock];
[_elements addObject:element];
[_lock unlock];
}
@end
i
上面的 ThreadSafeQueue
類有個init
方法唧喉,它初始化了一個 _elements
數(shù)組和一個 NSLock
實例。
這個類還有個 push:
方法,它先獲取鎖八孝、然后向數(shù)組中插入元素董朝、最終釋放鎖「甚耍可能會有許多線程同時調(diào)用 push:
方法子姜,但是[_elements addObject:element]
這行代碼在任何時候?qū)⒅粫谝粋€線程上運行。步驟如下:
1 線程 A 調(diào)用 push:
方法
2 線程 B 調(diào)用 push:
方法
3 線程 B 調(diào)用 [_lock lock]
- 因為當前沒有其他線程持有鎖楼入,線程 B 獲得了鎖
4 線程 A 調(diào)用 [_lock lock]
哥捕,但是鎖已經(jīng)被線程 B 占了所以方法調(diào)用并沒有返回-這會暫停線程 A 的執(zhí)行
5 線程 B 向 _elements
添加元素后調(diào)用 [_lock unlock]
。當這些發(fā)生時嘉熊,線程 A 的[_lock lock]
方法返回遥赚,并繼續(xù)將自己的元素插入 _elements
。
我們可以用 @synchronized結(jié)構(gòu)更簡要地實現(xiàn)這些:
@implementation ThreadSafeQueue
{
NSMutableArray *_elements;
}
- (instancetype)init
{
self = [super init];
if (self) {
_elements = [NSMutableArray array];
}
return self;
}
- (void)increment
{
@synchronized (self) {
[_elements addObject:element];
}
}
@end
在前面的例子中阐肤,”synchronized block”
與 [_lock lock]
和 [_lock unlock]
效果相同凫佛。你可以把它當成是鎖住 self
,仿佛 self就是個 NSLock
孕惜。
鎖在左括號 {后面的任何代碼運行之前被獲取到愧薛,在右括號 }
后面的任何代碼運行之前被釋放掉。這爽就爽在媽媽再也不用擔心我忘記調(diào)用 unlock
了衫画!
你可以給任何 Objective-C
對象上加個 @synchronized
毫炉。那么我們也可以在上面的例子中用 @synchronized(_elements)
來替代 @synchronized(self)
,效果是相同的碧磅。