在iOS开发中,不可避免的需要使用到多线程。但是使用多线程的过程中,如果使用不当,就会造成数据混乱,那要怎么保证多线程使用中不会因为访问同一个内存空间而造成数据混乱呢?这个时候锁(LOCK)就该闪亮登场了。本文会从以下几个方面介绍锁,希望对大家有帮助:
1)锁是什么以及为什么需要?
2)iOS中都有哪些锁?
3)锁的使用?
一、 锁是什么以及为什么需要?
锁是一种保证多线程并发执行安全的方式,避免 同一时间,多个线程同时读取并修改一个值而产 生混乱。
先来直观感受一下多线程不加锁的混乱,我们以火车站卖票为例,假设有20张票,同时有两个窗口售票:
- (void)ticketTest{
self.ticketsCount = 20;
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
for (NSInteger i = 0; i < 2; i++) {
dispatch_async(queue, ^{
for (int i = 0; i < 10; i++) {
[self sellingTickets];//多线程售票
}
});
}
}
- (void)sellingTickets{
NSInteger oldMoney = self.ticketsCount;
sleep(.2);
oldMoney -= 1;
self.ticketsCount = oldMoney;
NSLog(@"当前剩余票数-> %ld", oldMoney);
}
此时得到的结果是这样的
2019-01-08 15:08:55.954142+0800 LockDemo[19360:817602] 当前剩余票数-> 19
2019-01-08 15:08:55.954142+0800 LockDemo[19360:817605] 当前剩余票数-> 19
2019-01-08 15:08:55.954349+0800 LockDemo[19360:817605] 当前剩余票数-> 18
2019-01-08 15:08:55.954349+0800 LockDemo[19360:817602] 当前剩余票数-> 18
2019-01-08 15:08:55.954460+0800 LockDemo[19360:817605] 当前剩余票数-> 17
2019-01-08 15:08:55.954460+0800 LockDemo[19360:817602] 当前剩余票数-> 16
2019-01-08 15:08:55.954543+0800 LockDemo[19360:817605] 当前剩余票数-> 15
2019-01-08 15:08:55.954622+0800 LockDemo[19360:817602] 当前剩余票数-> 14
2019-01-08 15:08:55.954674+0800 LockDemo[19360:817605] 当前剩余票数-> 13
2019-01-08 15:08:55.955669+0800 LockDemo[19360:817602] 当前剩余票数-> 12
2019-01-08 15:08:55.956128+0800 LockDemo[19360:817605] 当前剩余票数-> 11
2019-01-08 15:08:55.956876+0800 LockDemo[19360:817602] 当前剩余票数-> 10
2019-01-08 15:08:55.957357+0800 LockDemo[19360:817605] 当前剩余票数-> 9
2019-01-08 15:08:55.957550+0800 LockDemo[19360:817602] 当前剩余票数-> 8
2019-01-08 15:08:55.957724+0800 LockDemo[19360:817605] 当前剩余票数-> 7
2019-01-08 15:08:55.957901+0800 LockDemo[19360:817602] 当前剩余票数-> 6
2019-01-08 15:08:55.958065+0800 LockDemo[19360:817605] 当前剩余票数-> 5
2019-01-08 15:08:55.958221+0800 LockDemo[19360:817602] 当前剩余票数-> 4
2019-01-08 15:08:55.958391+0800 LockDemo[19360:817605] 当前剩余票数-> 3
2019-01-08 15:08:55.958565+0800 LockDemo[19360:817602] 当前剩余票数-> 2
不加锁我们看到很明显的发生了混乱。我们对锁的需要也就不言而喻了。
二、 iOS中都有哪些锁?
从大的方向讲有两种锁:互斥锁、自旋锁。这两种类型下分别有自己对应的锁
互斥锁和自旋锁的对比:
这两种锁的相同点不必多说,都可以避免多线程访问同一个值发生混乱,重点说一下两种的不同点:
互斥锁:如果共享数据已经有其他线程加锁了,线程会进入休眠状态等待锁。一旦被访问的资源被解锁, 则等