什么是NSThread
NSThread是基于线程使用,轻量级的多线程编程方法(相对GCD和NSOperation),一个NSThread对象代表一个线程
NSThread用法
NSThread的创建方法比较简单:
- 可以动态创建(实例方法)初始化NSThread对象,需要自己调用- (void)start方法启动线程。
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket) object:nil];
thread1.name=@"thread1";
[thread1 start];
- 也可以通过NSThread的静态方法(类方法)快速创建并自动启动新线程;
[NSThread detachNewThreadSelector:@selector(threadRun) toTarget:self withObject:@"thread4"];
- 此外NSObject基类对象还提供了隐式快速创建performSelector,自动启动新线程
[self performSelectorInBackground:@selector(threadRun) withObject:@"thread5"];
线程之间通信
- 在当前线程执行操作
[self performSelector:@selector(threadRun)];
[self performSelector:@selector(threadRun) withObject:@"thread6"];
[self performSelector:@selector(threadRun) withObject:@"thread7" afterDelay:2.0];
- (在其他线程中)指定主线程执行操作
[self performSelectorOnMainThread:@selector(threadRun) withObject:nil
waitUntilDone:YES];
- (在主线程中)指定其他线程执行操作
[self performSelector:@selector(threadRun) onThread:newThread
withObject:nil waitUntilDone:YES];
//这里指定为某个线程
[self performSelectorInBackground:@selector(threadRun) withObject:nil];
//这里指定为后台线程
线程同步问题
最经典的售票问题:假如北京到上海的票还剩下100张,在售票处同时开了三个窗口进行售票...
我们开辟的三个线程就是三个窗口,同时进行售票:
卖票方法开始定义为:
- (void)sellTicket {
while (self.ticketsCount > 0) {
NSThread *thread = [NSThread currentThread];
[NSThread sleepForTimeInterval:2];
self.ticketsCount -- ;
NSLog(@"当前线程:%@\n剩余票数为:%zd ",thread.name, self.ticketsCount);
}
}
image.png
实现线程同步的几种方式:
- 第一种方式@synchronized(对象)关键字
- (void)sellTicket {
while (self.ticketsCount > 0) {
@synchronized(self) {
NSThread *thread = [NSThread currentThread];
[NSThread sleepForTimeInterval:2];
self.ticketsCount -- ;
NSLog(@"当前线程:%@\n剩余票数为:%zd ",thread.name, self.ticketsCount);
}
}
}
- 使用NSLock
NSLock 是 Cocoa 提供给我们最基本的锁对象,也是经常使用的,除 lock 和 unlock 方法外,NSLock 还提供了 tryLock 和 lockBeforeDate: 两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),并不会阻塞线程,直接返回 NO。lockBeforeDate: 方法会在所指定 Date 之前尝试加锁,如果在指定时间之前都不能加锁,则返回 NO。
self.threadLock = [[NSLock alloc]init];
- 使用NSCondition
self.condition = [[NSCondition alloc] init];
NSLock和NSCondition用法基本相同
- (void)lock;//加锁
- (void)unlock;//释放锁
while (self.ticketsCount > 0) {
[self.threadLock lock];
//[self.condition lock];
NSThread *thread = [NSThread currentThread];
[NSThread sleepForTimeInterval:2];
self.ticketsCount -- ;
NSLog(@"当前线程:%@\n剩余票数为:%zd ",thread.name, self.ticketsCount);
[self.threadLock unlock];
//[self.condition unlock];
}
image.png
参考链接:
https://blog.csdn.net/hbblzjy/article/details/51565590