5. 锁

2020-09-25  本文已影响0人  算命的李老师
==1.@synchronize==
==2.atomic==
==3.OSSpinlock==
自旋锁

循环等待访问,不释放当前资源,类似while(1),负责轻量级的+1,-1,如在引用计数的+1,-1操作

==4.NSRecursiveLock==
递归锁

为了解决NSLock在已加锁的情况下重复加锁,调用NSRecursiveLock的lock方法,可以使加锁之后仍然获取到锁,并且加锁。加锁解锁成对出现。解决多线程下递归方法的加锁。

==4.NSLock==

线程锁,为了解决线程同步问题

==5.dispatch_semaphore_t==

信号量,实现对线程同步,资源共享访问的信号量级锁

1.GCD信号量简介
//和GCD的group等用法一致,这个函数是创建一个dispatch_s`emaphore_类型的信号量
//并且创建的时候需要指定信号量的大小。
dispatch_semaphore_create(long value); // 创建信号量

//发送信号量。该函数会对信号量的值进行加1操作。
dispatch_semaphore_signal(dispatch_semaphore_t deem); // 发送信号量

//等待信号量。如果信号量值为0,那么该函数就会一直等待,也就是不返回(相当于阻塞当前线程)
//直到该函数等待的信号量的值大于等于1,该函数会对信号量的值进行减1操作,然后返回。
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等待信号量
2.用信号量机制使异步线程完成同步操作

两个任务虽然是异步的,但仍需要同步执行

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_group_t grp = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_async(grp, queue, ^{
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        NSLog(@"task1 begin : %@",[NSThread currentThread]);
        dispatch_async(queue, ^{
            NSLog(@"task1 finish : %@",[NSThread currentThread]);
            dispatch_semaphore_signal(sema);
        });
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        //先等待task1内的信号量 直到 task1 finish
    });
    dispatch_group_async(grp, queue, ^{
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        NSLog(@"task2 begin : %@",[NSThread currentThread]);
        dispatch_async(queue, ^{
            NSLog(@"task2 finish : %@",[NSThread currentThread]);
            dispatch_semaphore_signal(sema);
        });
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    });
    dispatch_group_notify(grp, dispatch_get_main_queue(), ^{
        NSLog(@"refresh UI");
    });
}
3 阻塞请求线程
dispatch_async(queue, 0), ^{
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    [网络请求:^{
        //请求回调
        dispatch_semaphore_signal(sema);  
    }];
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
//多个请求顺序执行
==6.dispatch_barrier_async和dispatch_barrier_sync==

栅栏方法,用GCD方式实现多读单写

dispatch_barrier_sync

需要等待栅栏执行完才会执行栅栏后面的任务

dispatch_barrier_async

无需等待栅栏执行完,会继续往下走(保留在队列里)

 dispatch_async(queue, ^{
        NSLog(@"----1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----2-----%@", [NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        //会等待内部执行完才往下走
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });
    dispatch_barrier_sync(queue, ^{
        //会等待内部执行完才往下走
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"----3-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----4-----%@", [NSThread currentThread]);
    });

线程安全的数组

- (id)objectAtIndex:(NSUInteger)index {
   __block id item = nil;
   dispatch_sync(self.readWriteQuene, ^{
       if (index <= self.array.count - 1) {
           item = [self.array objectAtIndex:index];
       }
   });
   return item;
}
- (nullable id)getFirstObject {
   __block id item = nil;
   dispatch_sync(self.readWriteQuene, ^{
       if (self.array.count > 0) {
           item = [self.array objectAtIndex:0];
       }
   });
   return item;
}
- (nullable id)getLastObject {
   __block id item = nil;
   dispatch_sync(self.readWriteQuene, ^{
       NSUInteger size = self.array.count;
       if (size > 0) {
           item = self.array[size - 1];
       }
   });
   return item;
}
//synchronized 效率最低
- (void)addObject:(id)anObject {
   dispatch_barrier_async(self.readWriteQuene, ^{
       [self.array addObject:anObject];
   });
}

- (void)insertObject:(id)anObject atIndex:(NSUInteger)index {
   dispatch_barrier_async(self.readWriteQuene, ^{
       [self.array insertObject:anObject atIndex:index];
   });
}
//还有很多操作数组的方法如removeLastObject
上一篇下一篇

猜你喜欢

热点阅读