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
相关文章推荐
- iOS开发点滴-添加阴影效果
- iOS LLDB调试精解
- iOS8新特性之交互式通知
- iOS dSYM文件结构剖析(上)
- iOS Crash文件的解析(一)
- iOS单元测试GHUnit + OCMock(使用cocoapods版)
- iOS基础:获取资源文件的方法
- iOS开发-你真的会用SDWebImage?(转发)
- IOS+openCV在Xcode的入门开发
- iOS实现左右循环滑动ScrollVIew
- IOS实现自动循环滚动广告--ScrollView的优化和封装
- iOS dataFormatter 8小时 误差
- ios runtime void method_exchangeImplementations
- iOS运行时与method swizzling
- iOS运行时与method swizzling
- [ios]CGContext 函数说明
- [ios]presentModalViewController和dismissModalViewControllerAnimated汇总
- iOS-正则表达式的使用
- iOS--串口通讯初始化
- 【转载】Xcode 4.1~4.6 + iOS 5、iOS 6免证书(iDP)开发+真机调试+生成IPA全攻略