最近遇到一个面试题,要求写一个Console程序,使用多线程不断打印一段字符串,当有用户键盘输入时停止打印,输入字符完毕回车后,继续打印.
由于我只熟悉iOS的api,就写了一个iOS的demo模拟效果.使用NSTimer轻松实现了.但不是面试官想要的,他提示他的意思想用我用多线程实现,使用一条线程阻塞另一条线程.
回去后我把代码和思路整理了一下:
其实考点是 多线程阻塞 和 递归
运行效果图
运行效果图.gif
//
// ViewController.m
// NSThreadDemo
//
// Created by YannChee
// Copyright © 2018年 YannChee. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *btn;
@property (strong,nonatomic)NSCondition *condition;
@property (assign,nonatomic)NSInteger index;
@property(nonatomic, assign) BOOL waitSignal;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.condition = [[NSCondition alloc] init];
// 设置按钮点击事件,模拟console 用户输入
[self.btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
// 已启动,默认打印hello
self.waitSignal = NO;
[NSThread detachNewThreadSelector:@selector(printHello) toTarget:self withObject:nil];
}
// 按钮点击事件,模拟console 用户输入
- (void)btnClick:(id)sender {
if ([self waitSignal] == NO) {
[self sendWaitSignal];
sleep(1);
NSLog(@"Console输入字符串");
} else {
[self signal];
NSLog(@"Console输入完毕回车");
}
}
/**
* 设置等待标识
*/
- (BOOL)sendWaitSignal{
[self.condition lock];
self.waitSignal = YES;
[self.condition unlock];
return self.waitSignal;
}
/**
* 获取等待标识
*/
- (BOOL)waitSignal{
return _waitSignal;
}
/**
* 发信号告诉线程不用在等待
*/
- (void)signal{
[self.condition lock];
self.waitSignal = NO;
// CPU发信号告诉线程不用在等待,可以继续执行
[self.condition signal];
[self.condition unlock];
}
- (void)printHello {
while (!self.waitSignal) {
// 每隔一秒,打印hello方法
sleep(1);
NSLog(@"hellow world =%zd",self.index ++);
}
[self.condition lock];
[self.condition wait];
[self.condition unlock];
// 递归调用,防止线程销毁
[self printHello];
}