iOS锁-NSLock
NSLock
下面是苹果官方文档的说法:
An object that coordinates the operation of multiple threads of execution within the same application.
Overview
An NSLock
object can be used to mediate access to an application’s global data or to protect a critical section of code, allowing it to run atomically.
Warning
The
NSLock
class uses POSIX threads to implement its locking behavior. When sending an unlock message to anNSLock
object, you must be sure that message is sent from the same thread that sent the initial lock message. Unlocking a lock from a different thread can result in undefined behavior.
You should not use this class to implement a recursive lock. Calling the lock
method twice on the same thread will lock up your thread permanently. Use the NSRecursiveLock
class to implement recursive locks instead.
Unlocking a lock that is not locked is considered a programmer error and should be fixed in your code. The NSLock
class reports such errors by printing an error message to the console when they occur.
下面是个人的理解以及一些例子
#import <Foundation/Foundation.h>
@interface NSLockTest : NSObject
- (void)forTest;
@end
#import "NSLockTest.h"
@interface NSLockTest()
@property (nonatomic,strong) NSArray *tickets;
@property (nonatomic,assign) int soldCount;
@property (nonatomic,strong) NSLock *lock;
@end
@implementation NSLockTest
- (void)forTest
{
self.tickets = @[@"南京-北京A101",@"南京-北京A102",@"南京-北京A103",@"南京-北京A104",@"南京-北京A105",@"南京-北京A106",@"南京-北京A107",@"南京-北京A108",@"南京-北京A109",@"南京-北京A110",@"南京-北京A111",@"南京-北京A112",@"南京-北京A113",@"南京-北京A114",@"南京-北京A115",@"南京-北京A116",@"南京-北京A117",@"南京-北京A118",@"南京-北京A119",@"南京-北京A120",@"南京-北京A121",@"南京-北京A122",@"南京-北京A123",@"南京-北京A124",@"南京-北京A125",@"南京-北京A126",@"南京-北京A127",@"南京-北京A128",@"南京-北京A129",@"南京-北京A130"];
//初始化NSLock
self.lock = [[NSLock alloc] init];
//第一窗口
NSThread *windowOne = [[NSThread alloc] initWithTarget:self selector:@selector(soldTicket) object:nil];
windowOne.name = @"一号窗口";
[windowOne start];
//第二窗口
NSThread *windowTwo = [[NSThread alloc] initWithTarget:self selector:@selector(soldTicket) object:nil];
windowTwo.name = @"二号窗口";
[windowTwo start];
//第三窗口
NSThread *windowThree = [[NSThread alloc] initWithTarget:self selector:@selector(soldTicket) object:nil];
windowThree.name = @"三号窗口";
[windowThree start];
//第四窗口
NSThread *windowFour = [[NSThread alloc] initWithTarget:self selector:@selector(soldTicket) object:nil];
windowFour.name = @"四号窗口";
[windowFour start];
}
-(void)soldTicket
{
//加锁
[self.lock lock];
if (self.soldCount == self.tickets.count) {
NSLog(@"=====%@ 剩余票数:%lu",[[NSThread currentThread] name],self.tickets.count-self.soldCount);
//解锁
[self.lock unlock];
return;
}
//延时卖票
[NSThread sleepForTimeInterval:0.2];
self.soldCount++;
NSLog(@"=====%@ %@ 剩%lu",[[NSThread currentThread] name],self.tickets[self.soldCount-1],self.tickets.count-self.soldCount);
//解锁
[self.lock unlock];
//一直卖票
[self soldTicket];
}
@end
注意点
1、NSLock不能加两次,否则就会被锁死
2、lock了之后,用完记得unlock
3、加锁的结果是正常的,每个窗口只能卖不同的票
4、不加锁,就会出现一张票在不同窗口售卖
=====一号窗口 南京-北京 A101 剩 29
=====二号窗口 南京-北京 A102 剩 28
=====三号窗口 南京-北京 A103 剩 27
=====四号窗口 南京-北京 A104 剩 26
=====一号窗口 南京-北京 A105 剩 25
=====二号窗口 南京-北京 A106 剩 24
=====三号窗口 南京-北京 A107 剩 23
=====四号窗口 南京-北京 A108 剩 22
.
.
.
三号窗口 剩余票数:0
四号窗口 剩余票数:0
一号窗口 剩余票数:0
二号窗口 剩余票数:0