少用@synchronized self 方法
//case 1 : @synchoronized self
//这样做,只要访问self,就会被锁,抢夺同一个锁,效率级低,还不如直接atomic 属性呢
- (void)setLockerStr:(NSString *)lockerStr {
@synchronized (self) {
_lockerStr = lockerStr;
}
}
- (NSString *)lockerStr {
__block NSString* blockStr;
@synchronized (self) {
blockStr = _lockerStr;
}
return blockStr;
}
//NSLock
- (void)setLockerStr:(NSString *)lockerStr {
[_lock lock];
_lockerStr = lockerStr;
[_lock unlock];
}
- (NSString *)lockerStr {
NSString* localStr;
[_lock lock];
localStr = _lockerStr;
[_lock unlock];
return localStr;
}
使用串行同步方法,而不是主动调用锁
//但是使用同步块,会调用拷贝block,在性能上也许不如直接锁
_syncQueue = dispatch_queue_create("syncQueue", nil);
- (void)setLockerStr:(NSString *)lockerStr {
dispatch_sync(_syncQueue, ^{
_lockerStr = lockerStr;
});
}
- (NSString *)lockerStr {
__block NSString* blockStr;
dispatch_sync(_syncQueue, ^{
blockStr = _lockerStr;
});
return blockStr;
}
如果改为并行呢,读可以多并行,而只有写是阻塞的呢
/**
dispatch_barrier_sync
dispatch_barrier_async
栅栏 block 必须单独执行,不能与其他块并行,只对并行队列有意义,因为串行队列的块总是按顺序来逐个执行的
这里再次说明下, sync 和 async 是决定是否阻塞当前线程,而决定执行是否并行,是由所放的队列来决定的
写方法表示,可以放到并行操作里面去写,但是由于 barrier 的特性,当前的 block 一定会再前面操作之后执行,像
一道栅栏一样横在哪里, 而读操作,由于要得到接口,所以是阻塞当前线程的,但是实际多线程里面却是并行操作的。
并发队列
| Read Read
| Read Read Read
| Write(barrier)
| Read Read
|
⤵️
时序
*/
- (void)setLockerStr:(NSString *)lockerStr {
dispatch_barrier_async(_asyncQueue, ^{
_lockerStr = lockerStr;
});
}
- (NSString *)lockerStr {
__block NSString* blockStr;
dispatch_barrier_sync(_asyncQueue, ^{
blockStr = _lockerStr;
});
return blockStr;
}