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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值