「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
@synchronized(递归锁)
@synchronized 概念
@synchronized 结构所做的事情跟 NSLock,更准确的说法应该是递归锁 NSRecursiveLock 类似。@synchronized 可以防止不同的线程同时执行同一段代码。但在某些情况下,相比于使用 NSLock 创建锁对象、加锁和解锁来说,@synchronized 用着更方便,可读性更高, 自然效率会比较低
@synchronized 作用
@synchronized 的作用是创建一个互斥锁,保证此时没有其它线程对 self 对象进行修改,保证代码的安全性。也就是包装这段代码是原子性的,安全的。这个是 objective-c 的一个锁定令牌,防止 self 对象在同一时间内被其他线程访问,起到保护线程安全的作用
@synchronized 用法
首先 @synchronized() 小括号内需要一个参数,这个参数就表示信号量。这个参数可以是任何对象,包括 self,或者是自定义的信号量。针对不同的操作应该定义不同的信号量
@synchronized() {…} 大括号中就是要加锁执行的代码,代码会操作一些数据。当开始执行代码时,意味着当前线程对其加锁了,当代码执行完后,自动解锁,其他线程才允许执行此段代码
- (void)lockData {
@synchronized(self){
// 关键代码;
}
}
@synchronized 常用场景
之前在iOS中的多线程(多线程的竞争)用到过
示例:
- (void)saleTicket{
while (1) {
NSLog(@"进行卖票-%@",[NSThread currentThread].name);
// @synchronized (锁对象),锁对象必须是一个,表示记录状态,一般用self就可以
@synchronized (self) {
NSInteger count = self.ticketCount;
if (count > 0 ){
self.ticketCount = count - 1;
NSLog(@"%@卖了一张票,还剩%ld张",[NSThread currentThread].name,(long)self.ticketCount);
}else{
NSLog(@"票卖完了");
break;
}
}
}
}
值得一提的是这个加锁机制是支持递归的,如果加锁的代码在当前线程中递归调用自身,那么会持续保持加锁状态,其余线程还是访问不了,只有当递归完成全部执行完后,或者出错报异常退出后,锁才会解开,释放信号量,其余线程才允许操作此段代码块