iOS同步锁 NSLock同步 PK GCD同步

在我们平常在代码中使用锁的时候,难免遇上死锁这种情况,在这个时候我们可以选择使用同步锁的方式,比较常用的就是NSLock。
在操作递归或者多次数据回调UI线程的时候最容易就出现这种死锁,比方说这样:

//主线程中
NSLock *theLock = [[NSLock alloc] init];
LockObj *obj = [[LockObj alloc] init];//线程dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    static void(^TestMethod)(int); 
    TestMethod = ^(int value) {
             [theLock lock]; if (value > 0) {
                 [obj method1];
                 sleep(5); 
                 TestMethod(value-1);
         }
           [theLock unlock]; 
  }; 
  TestMethod(5);
});
//线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
               sleep(1);
               [theLock lock];

               [obj method2]; 

              [theLock unlock];
  });

非常明显的,在线程1中的递归block中,锁会被多次的lock,所以自己也被阻塞了,死锁就这样造成了。
在一般的情况下,我们总以为添加了NSLock锁,线程就会变得安全,但是这也许可以为自己埋雷。

在翻阅过不少资料之后,广受推荐的仍然是GCD的同步锁。
有关于GCD:
GCD 有两种派发方式:同步派发和异步派发。值得注意的是这里的同步和异步指的是 “任务派发方式”,而非任务的执行方式。
一般我们在数据和UI调度的时候使用最广泛的就是(异步派发):
dispatch_async(queue, block) 做了两件事情:

  1. 将 block 添加到 queue 队列;
  2. 直接回到调用线程(不阻塞调用线程)。
dispatch_async (dispatch_get_global_queue, ^{
        //搞事情
          /*
          ***......
          */
    //回调UI线程:
  dispatch_async (dispatch_get_main_queue(),^{
      //回到主线程再搞事情

      });
        
});

相对用的较少的就是同步派发
dispatch_sync(queue, block)

  • 将 block 添加到 queue 队列;
  • 阻塞调用线程,等待 block() 执行结束,回到调用线程。
    实现同步锁可以利用这个特性。

那么如何实现GCD的同步锁呢?

  _syncQueue = dispatch_queue_create("com.effectiveObjectiveC.syncQueue", NULL);

- (NSString *)someString
{

     __weak NSString *localSomeString;
     dispatch_sync(_syncQueue, ^{
             localSomeString = _someString;
     });
     return localSomeString;
}

- (void)setSomeString:(NSString *)someString
{
     dispatch_sync(_syncQueue, ^{
         _someString = someString;
     });
}

通过这样的方式可以实现同步锁的效果,还能避免死锁的情况。
这里只是暂做记录,日后了解更多关于线程和死锁的问题,会陆续补充。
本文参考:
老谭:Objective-C 中不同方式实现锁(一)
老谭:Objective-C 中不同方式实现锁(二)
Effective Objective-C Notes:GCD 实现同步锁

你可能感兴趣的:(iOS同步锁 NSLock同步 PK GCD同步)