import “ViewController.h”
@interface ViewController ()
{
UILabel *showTicket;
int curtTicketNum; //当前票数
int saleTicketNum; // 销售票数
NSString *windowName; //窗口名字
NSCondition *condition;//线程锁
}
@end
@implementation ViewController
-
(void)viewDidLoad {
[super viewDidLoad];
curtTicketNum = 100;
self.view.backgroundColor = [UIColor brownColor];
// 卖票系统 分三个窗口同时销售
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 100, 100, 50);
[button setTitle:@"开始卖票" forState:UIControlStateNormal];
[button addTarget:self action:@selector(startSale) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
showTicket = [[UILabel alloc]init];
showTicket.frame = CGRectMake(200, 100, 100, 500);
showTicket.text = @"余票:100张";
showTicket.textAlignment = NSTextAlignmentCenter;
showTicket.numberOfLines = 5;
showTicket.textColor = [UIColor redColor];
[self.view addSubview:showTicket];
}
//三个窗口同时卖票
-(void)startSale
{
//初始化三个线程 每一个线程都是一个售票窗口
NSThread *window1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
window1.name = @”售票窗口1”;
[window1 start];
NSThread *window2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
window2.name = @"售票窗口2";
[window2 start];
NSThread *window3 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
window3.name = @"售票窗口3";
[window3 start];
// 线程锁 NSCondition 是一个线程锁(条件锁)
condition = [[NSCondition alloc]init];
}
-(void)saleTicket
{
// 没有使用线程锁 三个线程(窗口)会同时访问这个方法(卖票的方法) 所以 当剩余票数是0的时候 有可能其他两个线程 不知道剩余票数是0 还会同时访问,此事剩余票数会出现负数的情况
// 解决这个问题 可以使用线程锁
// 只允许一个线程访问完毕之后,另外一个线程再去访问
// 使用线程锁 值允许一个线程去访问
while (curtTicketNum>0) {
[condition lock];//锁住
[NSThread sleepForTimeInterval:0.1];
// 当前票数(剩余)
curtTicketNum -=1;
// 卖的票数
saleTicketNum = 100-curtTicketNum;
windowName = [NSThread currentThread].name;
if (curtTicketNum>0) {
[condition unlock]; //当一个窗口卖完票后在解锁
}
[self performSelectorOnMainThread:@selector(upDataUI) withObject:nil waitUntilDone:YES];
}
curtTicketNum = 100;
}
//更新界面
-(void)upDataUI
{
showTicket.text = [NSString stringWithFormat:@”已经销售%d 还剩%d 当前窗口是%@”,saleTicketNum,curtTicketNum,windowName];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end