多线程篇-NSThread-synchronized(互斥锁)
前言
这里的话我假设自己开了一家餐厅,然后座位为15个,支持网络预订座位,接单为两天电脑。
我和我老婆专门为接单员,有可能会接到同一单,然后为两个不同人同时预定一个位置,这里我们就得用到互斥锁了
撸码
- 代码
@interface ViewController ()
//座位
@property(nonatomic,assign) int seat;
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 座位一共15个
self.seat = 15;
// 开启一个线程 也就是我老婆
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(ReserveSeat) object:nil];
thread1.name = @"老婆";
[thread1 start];
// 开启一个线程 也就是我自己
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(ReserveSeat) object:nil];
thread2.name = @"自己";
[thread2 start];
}
/**
* 开线程
*/
-(void)ReserveSeat{
// 我们必须座位预定完 也就是一直循环 直到seat属性没有值
while (true) {
// 判断如果座位大于0 客户就可以预订
if(self.seat > 0)
{
NSLog(@"预定%d号座位 ------%@",self.seat,[NSThread currentThread]);
self.seat --;
}else{
NSLog(@"没有座位了 ------%@",[NSThread currentThread]);
break;
}
}
}
@end
- 结果
针对上面的话 那我们只能想出一个方法 就是当我在给客人预订的时候 我老婆是不能操作这个座位的 除非那个客户不要了 我不操作那个座位了
我老婆才能去操作 那么就引出了互斥锁这个东西 我操作的时候就锁着它
- 代码
/**
* 开线程
*/
-(void)ReserveSeat{
// 我们必须座位预定完 也就是一直循环 直到seat属性没有值
while (true) {
// 注意,锁一定要是所有线程共享的对象
// 如果代码中只有一个地方需要加锁,大多都使用 self
@synchronized(self) {
// 判断如果座位大于0 客户就可以预订
if(self.seat > 0)
{
NSLog(@"预定%d号座位 ------%@",self.seat,[NSThread currentThread]);
self.seat --;
}else{
NSLog(@"没有座位了 ------%@",[NSThread currentThread]);
break;
}
}
}
}
- 结果
- 扩展
互斥锁小结
保证锁内的代码,同一时间,只有一条线程能够执行!
互斥锁的锁定范围,应该尽量小,锁定范围越大,效率越差!
速记技巧 [[NSUserDefaults standardUserDefaults] synchronize];
互斥锁参数
能够加锁的任意 NSObject 对象
注意:锁对象一定要保证所有的线程都能够访问
如果代码中只有一个地方需要加锁,大多都使用 self,这样可以避免单独再创建一个锁对象
结束
本章到此结束
欢迎各位码友随意转载并指正