@interface NSOperationViewController ()
{
NSOperationQueue *queueOther;
NSOperationQueue *queueTicket;
BOOL isStopSale;
}
@end
NSInteger ticketsCount = 20; // 剩余票数
NSInteger windowsCount = 3; // 售票窗口
- (void)someoneSaleTicket
{
// 队列
queueTicket = [[NSOperationQueue alloc] init];
queueTicket.maxConcurrentOperationCount = windowsCount;
// 任务,售票窗口
for (int i = 0; i < windowsCount; i++)
{
NSString *name = [NSString stringWithFormat:@"窗口%@", @(i + 1)];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(someoneBuyTicket:) object:name];
[queueTicket addOperation:operation];
}
ticketsCount = 20;
isStopSale = NO;
}
- (void)stopToSaleTicket
{
if (queueTicket)
{
[queueTicket cancelAllOperations];
isStopSale = YES;
NSLog(@"意外事故,暂停营业");
}
}
- (void)pauseToSaleTicket
{
if (queueTicket)
{
queueTicket.suspended = !queueTicket.isSuspended;
isStopSale = YES;
NSLog(@"%@", (queueTicket.isSuspended ? @"下班了,停止售票" : @"上班了,开始售票"));
}
}
- (void)someoneBuyTicket:(id)object
{
while (1)
{
if (isStopSale)
{
break;
}
// 互斥锁
@synchronized (self) {
if (ticketsCount > 0)
{
// 如果还有票,继续售卖
NSInteger count = arc4random() % 3 + 1; // 在窗口购买任意n+1张票
if (ticketsCount == 1)
{
count = 1;
}
ticketsCount -= count; // 剩余票数
NSLog(@"在 %@ 买了 %ld 张,还剩下 %ld 张。", object, count, ticketsCount);
[NSThread sleepForTimeInterval:0.2];
}
else
{
// 如果已卖完,关闭售票窗口
if ([NSThread currentThread].isCancelled)
{
NSLog(@"关闭 %@", object);
// [NSThread exit]; // 终止线程
if (queueTicket)
{
[queueTicket cancelAllOperations];
}
break;
}
else
{
NSLog(@"在 %@ 买票时,没有票了。", object);
// 给当前线程标记为取消状态
[[NSThread currentThread] cancel];
// 停止当前线程的runLoop
CFRunLoopStop(CFRunLoopGetCurrent());
}
}
}
}
}
2018-03-07 14:06:07.907 DemoThread[1805:173069] 在 窗口2 买了 1 张,还剩下 19 张。
2018-03-07 14:06:08.180 DemoThread[1805:173087] 在 窗口1 买了 2 张,还剩下 17 张。
2018-03-07 14:06:08.416 DemoThread[1805:173072] 在 窗口3 买了 1 张,还剩下 16 张。
2018-03-07 14:06:08.687 DemoThread[1805:173069] 在 窗口2 买了 2 张,还剩下 14 张。
2018-03-07 14:06:08.958 DemoThread[1805:173087] 在 窗口1 买了 2 张,还剩下 12 张。
2018-03-07 14:06:09.233 DemoThread[1805:173072] 在 窗口3 买了 1 张,还剩下 11 张。
2018-03-07 14:06:09.500 DemoThread[1805:173069] 在 窗口2 买了 3 张,还剩下 8 张。
2018-03-07 14:06:09.773 DemoThread[1805:173087] 在 窗口1 买了 1 张,还剩下 7 张。
2018-03-07 14:06:10.047 DemoThread[1805:173072] 在 窗口3 买了 3 张,还剩下 4 张。
2018-03-07 14:06:10.318 DemoThread[1805:173069] 在 窗口2 买了 2 张,还剩下 2 张。
2018-03-07 14:06:10.592 DemoThread[1805:173087] 在 窗口1 买了 1 张,还剩下 1 张。
2018-03-07 14:06:10.860 DemoThread[1805:173072] 在 窗口3 买了 1 张,还剩下 0 张。
2018-03-07 14:06:11.133 DemoThread[1805:173069] 在 窗口2 买票时,没有票了。
2018-03-07 14:06:11.134 DemoThread[1805:173087] 在 窗口1 买票时,没有票了。
2018-03-07 14:06:11.135 DemoThread[1805:173072] 在 窗口3 买票时,没有票了。
2018-03-07 14:06:11.135 DemoThread[1805:173069] 关闭 窗口2
2018-03-07 14:06:11.136 DemoThread[1805:173087] 关闭 窗口1
2018-03-07 14:06:11.136 DemoThread[1805:173072] 关闭 窗口3