您的位置:首页 > 移动开发 > IOS开发

iOS开发--多线程编程(二)NSThread买票

2016-04-26 20:10 381 查看
前面已经有说过 NSThread,只是前面的下载图片还不够形象,这里补充一个买票的例子,这里需要注意的是 <pre name="code" class="objc">NSCondition 一定要初始化一个对象,如果只是声明了,但是忘了初始化的话,还是得不到理想的效果,即 票出现 负值


#import "ViewController.h"

@interface ViewController ()
{
UILabel *showLab;
//    当前余票
int curTicketNumber;
//    售票窗口名称
NSString *windowName;
//    已售票数
int saleTicketNumber;
//    NSCondition 是一个线程锁
NSCondition *condition;
}
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor cyanColor];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 50, 150, 30);
[button setTitle:@"开始卖票" forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button addTarget:self action:@selector(startSale) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];

showLab = [[UILabel alloc]initWithFrame:CGRectMake(100, 300, 200, 100)];
showLab.numberOfLines = 3;
curTicketNumber = 100;
showLab.text = @"剩余100张票";
showLab.textColor = [UIColor blackColor];
[self.view addSubview:showLab];

condition = [[NSCondition alloc]init];

}

- (void)startSale{
NSThread *firstWindow = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
firstWindow.name = @"窗口1";
[firstWindow start];

NSThread *twoWindow = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
twoWindow.name = @"窗口2";
[twoWindow start];

NSThread *threeWindow = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
threeWindow.name = @"窗口3";
[threeWindow start];
}

- (void)saleTicket{
while (curTicketNumber > 0) {
//        使用线程锁只允许一个线程去访问
[condition lock];

//        没有使用线程锁,三个线程(窗口)会同时访问这个方法(卖票的方法),这个 当剩余票数是0 的时候有可能其他两个线程  不知道剩余票数是0 还会继续访问 这样就会有 剩余票数是负数的情况

//        解决这个问题可以使用线程锁,只允许一个线程 访问完毕之后另外一个线程再访问
[NSThread sleepForTimeInterval:0.05];
//        当前票数 -1
curTicketNumber -= 1;
//        已买出的票数
saleTicketNumber = 100 - curTicketNumber;
//        此刻卖票的窗口即为现在正在工作的线程
windowName = [NSThread currentThread].name;
if (curTicketNumber > 0) {
[condition unlock]; //解锁

}
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
}

}

- (void)updateUI{
NSLog(@"现在正在售票的窗口是:%@   已卖:%d张票, 还剩:%d张票", windowName, saleTicketNumber, curTicketNumber);
showLab.text  = [NSString stringWithFormat:@"已经销售%d张票\n剩余%d张票\n当前销售窗口是%@",saleTicketNumber,curTicketNumber,windowName];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: