线程同步

@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);
}

你可能感兴趣的:(线程同步)