1.什么是线程同步
此处的同步不是一起的意思,而是协同的意思。假设线程A,B,C,A完成某件事之后,通知B去做什么,B又会通知C什么时候做什么。
还有比如我们有一个变量不允许多个线程一起访问那么就可以采用同步的方式。
2.资源竞争--死锁
程序中多个线程访问统一资源,这叫资源竞争。而由于资源竞争不当,可能导致线程相互等待而无法进行下去的情况,被称之为,死锁。
3.线程通信
多个线程之间彼此通信,有多种实现方式。
开始多线程编程:
(1)早期的单线程编程,我们在一个线程中执行UI操作和数据操作,这就势必会导致相互等待的情况出现。
(2)在iOS中提供了三种多线程编程的方式,包括:NSThread、NSOperation、GCD。
(3)因为每个iOS进程都将UI线程作为主线程、而其他方式创建的线程都是不属于Cocotouch框架的,所以不应该在其中对UI界面进行操作。
NSThread(相当于线程)
优点:轻量级、使用简单。
缺点:需要自己管理线程的生命周期、线程同步、线程的同步锁很耗费资源。
有两种创建NSThread的方式:
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
这种方式创建线程之后直接执行方法。
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument NS_AVAILABLE(10_5, 2_0);
这种方式要调用start方法。
停止的方式,先cancle掉,这时候线程还是会继续执行,根据这个标志位置:执行exit操作。
线程同步的方式:lock。
可以设置线程优先级。0~1.
当前线程:[NSThread currentThread];
主线程:[NSThread mainThread];
实例:
#import "ViewController.h"
@interface ViewController ()
{
NSLock *lock;
NSCondition *condition;
}
@end
int ticket = 100;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
lock = [[NSLock alloc]init];
condition = [[NSCondition alloc]init];
[NSThread detachNewThreadSelector:@selector(saleTicket:) toTarget:self withObject:[NSNumber numberWithInt:1]];
[NSThread detachNewThreadSelector:@selector(saleTicket:) toTarget:self withObject:[NSNumber numberWithInt:2]];
[NSThread detachNewThreadSelector:@selector(saleTicket:) toTarget:self withObject:[NSNumber numberWithInt:3]];
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:[NSNumber numberWithInt:3]];
}
-(void)run
{
while (YES) {
[condition lock];
[NSThread sleepForTimeInterval:3.0];
[condition unlock];
}
}
-(void)saleTicket:(NSNumber *)ThreadId
{
while (YES) {
// [lock lock]; //线程同步保证数据一致性,这对于增删改比较有用,区分查的操作
[condition lock];
[condition wait];
if (!ticket) {
NSLog(@"票卖光了");
break;
}else{
ticket--;
NSLog(@"还剩 %d 张票",ticket);
if (ticket==50) {
NSLog(@"突发情况,不卖了");
//如何停止一个线程,生命周期(start、excuting、finished、cancle) EXIT根据标志位退出线程。
NSThread *thread = [NSThread currentThread];
[thread cancel];
if (thread.isCancelled) {
[NSThread exit];
}
}
}
[condition unlock];
// [lock unlock];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end