iOS多线程编程——NSThread的使用(买票实例)

多线程的使用,主要是为了提高运行效率,如果涉及到到同一个方法,或同一个数据的操作时,就避免不了造成资源抢夺的情况,这样情况下会出现异常。为了避免异常,需要进行加锁处理。

// 剩余票数
NSInteger ticketCount = 10;
// 购票窗口
- (void)buyTicket
{
    NSThread *window1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    window1.name = @"深圳北站";
    [window1 start];
    
    NSThread *window2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    window2.name = @"深圳福田站";
    [window2 start];
    
    ticketCount = 10;
}
// 购票-加锁
- (void)saleTicket
{
    while (1)
    {
        // 互斥锁
        @synchronized (self) {
            if (ticketCount > 0)
            {
                // 如果还有票,继续售卖
                NSInteger count = arc4random() % 3 + 1; // 在窗口购买任意n+1张票
                if (ticketCount == 1)
                {
                    count = 1;
                }
                ticketCount -= count; // 剩余票数
                NSLog(@"在 %@ 窗口买了 %ld 张,还剩下 %ld 张。", [NSThread currentThread].name, count, ticketCount);
                
                [NSThread sleepForTimeInterval:0.2];
            }
            else
            {
                // 如果已卖完,关闭售票窗口
                if ([NSThread currentThread].isCancelled)
                {
                    NSLog(@"关闭 %@ 窗口", [NSThread currentThread].name);
//                    [NSThread exit]; // 终止线程
                    break;
                }
                else
                {
                    NSLog(@"在 %@ 窗口买票时,没有票了。", [NSThread currentThread].name);
                    
                    // 给当前线程标记为取消状态
                    [[NSThread currentThread] cancel];
                    // 停止当前线程的runLoop
                    CFRunLoopStop(CFRunLoopGetCurrent());
                }
            }
        }
    }
}
// 加锁情况下购票,执行结果正常
2018-03-06 14:53:39.861 DemoThread[6605:1274282] 在 深圳北站 窗口买了 1 张,还剩下 9 张。
2018-03-06 14:53:40.063 DemoThread[6605:1274283] 在 深圳福田站 窗口买了 3 张,还剩下 6 张。
2018-03-06 14:53:40.266 DemoThread[6605:1274282] 在 深圳北站 窗口买了 2 张,还剩下 4 张。
2018-03-06 14:53:40.471 DemoThread[6605:1274283] 在 深圳福田站 窗口买了 2 张,还剩下 2 张。
2018-03-06 14:53:40.674 DemoThread[6605:1274282] 在 深圳北站 窗口买了 1 张,还剩下 1 张。
2018-03-06 14:53:40.879 DemoThread[6605:1274283] 在 深圳福田站 窗口买了 1 张,还剩下 0 张。
2018-03-06 14:53:41.085 DemoThread[6605:1274282] 在 深圳北站 窗口买票时,没有票了。
2018-03-06 14:53:41.085 DemoThread[6605:1274283] 在 深圳福田站 窗口买票时,没有票了。
2018-03-06 14:53:41.085 DemoThread[6605:1274282] 关闭 深圳北站 窗口
2018-03-06 14:53:41.086 DemoThread[6605:1274283] 关闭 深圳福田站 窗口
// 购票-未加锁
- (void)saleTicket
{
    while (1)
    {
            if (ticketCount > 0)
            {
                // 如果还有票,继续售卖
                NSInteger count = arc4random() % 3 + 1; // 在窗口购买任意n+1张票
                if (ticketCount == 1)
                {
                    count = 1;
                }
                ticketCount -= count; // 剩余票数
                NSLog(@"在 %@ 窗口买了 %ld 张,还剩下 %ld 张。", [NSThread currentThread].name, count, ticketCount);
                
                [NSThread sleepForTimeInterval:0.2];
            }
            else
            {
                // 如果已卖完,关闭售票窗口
                if ([NSThread currentThread].isCancelled)
                {
                    NSLog(@"关闭 %@ 窗口", [NSThread currentThread].name);
//                    [NSThread exit]; // 终止线程
                    break;
                }
                else
                {
                    NSLog(@"在 %@ 窗口买票时,没有票了。", [NSThread currentThread].name);
                    
                    // 给当前线程标记为取消状态
                    [[NSThread currentThread] cancel];
                    // 停止当前线程的runLoop
                    CFRunLoopStop(CFRunLoopGetCurrent());
                }
            }
    }
}
// 未加锁情况下,购买异常
2018-03-06 14:58:35.457 DemoThread[6648:1278848] 在 深圳北站 窗口买了 3 张,还剩下 7 张。
2018-03-06 14:58:35.457 DemoThread[6648:1278849] 在 深圳福田站 窗口买了 2 张,还剩下 5 张。
2018-03-06 14:58:35.661 DemoThread[6648:1278849] 在 深圳福田站 窗口买了 2 张,还剩下 0 张。
2018-03-06 14:58:35.661 DemoThread[6648:1278848] 在 深圳北站 窗口买了 3 张,还剩下 2 张。
2018-03-06 14:58:35.864 DemoThread[6648:1278848] 在 深圳北站 窗口买票时,没有票了。
2018-03-06 14:58:35.864 DemoThread[6648:1278849] 在 深圳福田站 窗口买票时,没有票了。
2018-03-06 14:58:35.864 DemoThread[6648:1278848] 关闭 深圳北站 窗口
2018-03-06 14:58:35.864 DemoThread[6648:1278849] 关闭 深圳福田站 窗口







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

番薯大佬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值