前面已经有说过 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