之前已经了解了NSThread如何创建线程,以及线程当中的2个属性。
现在我们用一个购票案例,来模拟一下线程当中资源共享的问题。
1.创建一个售票类
//
// TicketManager.h
// TestThread
#import <Foundation/Foundation.h>
@interface TicketManager : NSObject
// 开始卖票
- (void)startToSale;
@end
//
// TicketManager.m
// TestThread
#import "TicketManager.h"
#define TotalTickets 50 //总票数
@interface TicketManager()
// 剩余票数
@property(nonatomic,assign) int limitTickets;
// 卖出票数
@property(nonatomic,assign) int saleCount;
// 线程一(北京售票点)
@property(nonatomic,strong)NSThread *threadBJ;
// 线程二(上海售票点)
@property(nonatomic,strong)NSThread *threadSH;
@end
@implementation TicketManager
// 初始化方法中,创建2个线程
- (instancetype)init
{
if (self = [super init]) {
self.limitTickets = TotalTickets;
self.threadBJ = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
[self.threadBJ setName:@"北京售票点"];
self.threadSH = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
[self.threadSH setName:@"上海售票点"];
}
return self;
}
// 卖票的动作
- (void)sale
{
while (true) {
// 如果还有余票
if (self.limitTickets > 0) {
[NSThread sleepForTimeInterval:0.5];
self.limitTickets--;
self.saleCount = TotalTickets - self.limitTickets;
NSLog(@"%@:当前余票:%d,已经售出:%d", [NSThread currentThread].name,self.limitTickets, self.saleCount);
}
}
}
// 开始卖票了(开始执行2个线程)
- (void)startToSale
{
[self.threadBJ start];
[self.threadSH start];
}
@end
2.我们到控制器里 引入这个类,调用开始卖票的方法
#import "TicketManager.h"
TicketManager *mgr = [[TicketManager alloc] init];
[mgr startToSale];
从打印的log,可以看出卖票出问题啦。
如果来解决2个售票点资源共享的问题呢?
用锁的思想。
在这里具体就是用@synchronized
,把买票的逻辑处理放入其中。
// 卖票的动作
- (void)sale
{
while (true) {
@synchronized (self) {
// 如果还有余票
if (self.limitTickets > 0) {
// 这句是用来模拟卖票的时间间隔
[NSThread sleepForTimeInterval:0.5];
self.limitTickets--;
self.saleCount = TotalTickets - self.limitTickets;
NSLog(@"%@:当前余票:%d,已经售出:%d", [NSThread currentThread].name,self.limitTickets, self.saleCount);
}
}
}
}
这样就解决了2个线程(2个售票点)共享资源(共同售卖50张票)的问题。