有时候代码中会出现多条线程抢夺同一块资源,这是我们就需要对这块资源进行加锁; demo讲解
1、NSLock
NSLock 遵循 NSLocking 协议,lock 方法是加锁,unlock 是解锁,tryLock 是尝试加锁,如果失败的话返回 NO,lockBeforeDate: 是在指定Date之前尝试加锁,如果在指定时间之前都不能加锁,则返回NO。
代码讲解
lockArray = [NSMutableArray array];
lock = [[NSLock alloc] init];
NSLog(@"开始执行lock");
//利用GCD并行多个线程并且等待所有线程结束之后再执行其它任务
dispatch_group_t group = dispatch_group_create();
//线程1
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程一
[self lookLock];
});
NSLog(@"第一个执行了lock");
//线程2
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程二
[self lookLock];
});
NSLog(@"执行结束lock");
执行结果 :
2018-11-22 10:07:13.415401+0800 StoryBoard[19961:3771942] 开始执行lock
2018-11-22 10:07:13.415545+0800 StoryBoard[19961:3771942] 第一个执行了lock
2018-11-22 10:07:13.415562+0800 StoryBoard[19961:3774937] 进来了lock
2018-11-22 10:07:13.415693+0800 StoryBoard[19961:3771942] 执行结束lock
2018-11-22 10:07:13.415696+0800 StoryBoard[19961:3774937] 锁了lock
2018-11-22 10:07:13.415700+0800 StoryBoard[19961:3774934] 进来了lock
2018-11-22 10:07:13.415768+0800 StoryBoard[19961:3774937] 解锁lock
2018-11-22 10:07:13.416035+0800 StoryBoard[19961:3774934] 锁了lock
2018-11-22 10:07:13.416114+0800 StoryBoard[19961:3774934] 解锁lock
2018-11-22 10:07:13.416193+0800 StoryBoard[19961:3774934] 结束lock
上面 我们初始化了数组lockArray 和
NSLock,定义了一个lock方法:先加锁、然后向数组中插入元素,然后解锁;锁的使用就是可能多个线程同时调用lock这个
方法,可能这个里面的某些功能只能在一个线程上运行;
1 线程 A 和 线程 B调用 lock方法
2 线程 A 调用 [lock lock]时 因为当前没有其他线程持有锁,线程 A 获得了锁
3 线程 BA 调用 [lock lock],但是锁已经被线程A占了所以方法调用并没有返回,就会暂停线程B的执行
4 线程A向lockArray添加元素后调用[lock unlock]。之后线程B的[lock lock]方法返回,并继续将自己的元素插入lockArry。
2、@synchronized
-
@synchronized 结构做的事情跟lock锁类似;它防止不同的线程同时执行同一段代码。但是相比较NSlock
@synchronized 更加方便,可读性也高 -
@synchronized
的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改。这个是objective-c的一个锁定令牌,防止self对象在同一时间内被其它线程访问,起到线程的保护作用。 -
@synchronized使用格式
@synchronized(锁对象){ 需要锁的代码};
-
@synchronized的优缺点
优点:能有效防止因多线程抢夺资源造成的数据安全 缺点:需要消耗大量的cpu资源
-
@synchronized的使用情况一般是多条线程抢夺同一块资源
代码讲解//@synchronized dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程一 [self synchronized]; }); NSLog(@"第一个执行了synchronized"); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程二 [self synchronized]; });
运行结果
2018-11-22 10:07:13.416390+0800 StoryBoard[19961:3774934] 第一个执行了synchronized
2018-11-22 10:07:13.416397+0800 StoryBoard[19961:3774937] 进来了synchronized
2018-11-22 10:07:13.416923+0800 StoryBoard[19961:3774934] 进来了synchronized
2018-11-22 10:07:13.416924+0800 StoryBoard[19961:3774937] 锁了synchronized
2018-11-22 10:07:13.417139+0800 StoryBoard[19961:3774937] 解锁synchronized
2018-11-22 10:07:13.417155+0800 StoryBoard[19961:3774934] 锁了synchronized
2018-11-22 10:07:13.417697+0800 StoryBoard[19961:3774934] 解锁synchronized