iOS笔记

iOS锁

2021-08-19  本文已影响0人  狗蛋的春天

NSLock

  nslock是互斥锁,非递归所,连续加锁大于等于两次[self.lock lock]会造成死锁

@synchronized

  @synchronized 互斥锁(当中的递归锁)跟(NSLock, 更准确的说法应该是递归锁NSRecursiveLock)类似:它可以防止不同的线程同时执行同一段代码。但在某些情况下,相比于使用 NSLock 创建锁对象、加锁和解锁来说,@synchronized 用着更方便,可读性更高, 自然效率会比较低。
只有一个线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    @synchronized(self) {
        sleep(2);
        NSLog(@"线程1");
      }
      sleep(1);
      NSLog(@"线程1解锁成功");
  });

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      @synchronized(self) {
          NSLog(@"线程2");
      }
 });
 打印    线程1---->线程2----->线程1解锁成功
  @synchronized(object) 指令使用的 object 为该锁的唯一标识,只有当标识相同时,才满足互斥,所以如果线程 2 中的                   
  @synchronized(self) 改为@synchronized(self.view),则线程2就不会被阻塞
  @synchronized 指令实现锁的优点就是我们不需要在代码中显式的创建锁对象,便可以实现锁的机制,但作为一种预防措施, 
  @synchronized 块会隐式的添加一个异常处理例程来保护代码,该处理例程会在异常抛出的时候自动的释放互斥锁。
  如果在 @sychronized(object){} 内部 object 被释放或被设为 nil,从测试的结果来看,的确没有问题,但如果 object 一开始就是 
  nil,则失去了锁的功能。但 @synchronized([NSNull null]) 是完全可以的。

  递归锁: 同一个线程可以重复的加锁而不会导致死锁(互斥锁: 同一个线程重复加锁会导致死锁) ,加的递归锁全部执行完后 才会把资源让给别的线程。不同的线程要求加锁会陷入等待. 
  传入的object必须是有地址的指针的,才能起到加锁效果,如果传入的对象释放了nil就起不到加锁的作用。

GCD信号量 dispatch_semaphore_create(1) 赋值为1就代表锁

      信号量置为1 每次都只有一个线程在执行
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //任务1
     dispatch_async(queue, ^{
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
      NSLog(@"run task 1");
      sleep(1);
      NSLog(@"complete task 1");
      dispatch_semaphore_signal(semaphore);
    });
    //任务2
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);
    });
    //任务3
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);
    });
上一篇 下一篇

猜你喜欢

热点阅读