@synchronized 同步锁
使用@synchronized解决线程同步问题相比较NSLock要简单一些,日常开发中也更推荐使用此方法。首先选择一个对象作为同步对象(一般使用self),然后将”加锁代码”(争夺资源的读取、修改代码)放到代码块中。@synchronized中的代码执行时先检查同步对象是否被另一个线程占用,如果占用该线程就会处于等待状态,直到同步对象被释放
static NSObject *lockObj = nil;
if (lockObj == nil) {
lockObj = [[NSObject alloc] init];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"A 准备好了");
@synchronized(lockObj) {
NSLog(@"A 进去了");
[NSThread sleepForTimeInterval:10];
NSLog(@"A 出来了");
}
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"B 准备好了");
@synchronized(lockObj) {
NSLog(@"B 进去了");
[NSThread sleepForTimeInterval:5];
NSLog(@"B 出来了");
}
});
NSLock 同步锁
OS中对于资源抢占的问题可以使用同步锁NSLock来解决,使用时把需要加锁的代码(以后暂时称这段代码为”加锁代码“)放到NSLock的lock和unlock之间,一个线程A进入加锁代码之后由于已经加锁,另一个线程B就无法访问,只有等待前一个线程A执行完加锁代码后解锁,B线程才能访问加锁代码。需要注意的是lock和unlock之间的”加锁代码“应该是抢占资源的读取和修改代码,不要将过多的其他操作代码放到里面,否则一个线程执行的时候另一个线程就一直在等待,就无法发挥多线程的作用了
static NSLock *lockMain = nil;
if (lockMain == nil) {
lockMain = [[NSLock alloc] init];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lockMain lock];
NSLog(@"A thread begin +!");
[NSThread sleepForTimeInterval:2];
NSLog(@"A thread + done and unlock!");
[lockMain unlock];
[lockMain lock];
NSLog(@"A thread begin -!");
[NSThread sleepForTimeInterval:2];
NSLog(@"A thread - done and unlock!");
[lockMain unlock];
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lockMain lock];
NSLog(@"B thread begin *!");
[NSThread sleepForTimeInterval:2];
NSLog(@"B thread * done and unlock!");
[lockMain unlock];
[lockMain lock];
NSLog(@"B thread begin /!");
[NSThread sleepForTimeInterval:2];
NSLog(@"B thread / done and unlock!");
[lockMain unlock];
});
GCD解决资源抢占问题 dispatch_semaphore_t
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
for (int i = 0; i < 100; i++)
{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
NSLog(@"%i",i);
sleep(1);
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}
网友评论