当前位置:网站首页>多线程四部曲之NSThread
多线程四部曲之NSThread
2022-06-11 03:17:00 【chabuduoxs】
NSThread是什么?
众所周知在iOS多线程开发主要有四种方式,NSThread就是其中一种。
下面是apple官方给出的解释
可以看出NSThread是apple封装的一个线程类,开发人员可以对线程进行操作,并且可以监控线程状态。NSThread是基于线程使用,轻量级的多线程编程方法(相对GCD和NSOperation),一个NSThread对象代表一个线程
NSThread的使用
NSThread的创建
该类的创建方法比较简单,大致可以分为动态和静态两种方法。
- 1.可以动态创建(实例方法)初始化NSThread对象,需要自己调用- (void)start方法启动线程。
// 参数意义
/*target selector指定的消息发送到的对象。 selector 要发送消息到target的选择器。此选择器必须只接受一个参数,并且不得具有返回值。 argument 传递给目标的单个参数。可能是nil。 */
NSThread *firstThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
firstThread.name = @"thread1";
[firstThread start];
- 2.也可以通过NSThread的静态方法(类方法)快速创建并自动启动新线程
// 分离新线程,并使用指定的选择器作为线程入口点。
[NSThread detachNewThreadSelector:@selector(pressBack:) toTarget:self withObject:@"thread4"];
- 3.此外NSObject基类对象还提供了隐式快速创建performSelector,自动启动新线程
[self performSelectorInBackground:@selector(threadRun) withObject:@"thread5"];
一些线程通信
// 当前线程执行操作
// [self performSelector:@selector(threadRun)];
// [self performSelector:@selector(threadRun) withObject:@"thread6"];
// // 延迟n秒后进入线程
// [self performSelector:@selector(threadRun) withObject:@"thread7" afterDelay:2.0];
// // 在其他线程中指定主线程操作
// [self performSelectorOnMainThread:@selector(threadRun) withObject:nil
// waitUntilDone:YES];
// // (在主线程中)指定其他线程执行操作
// [self performSelector:@selector(threadRun) onThread:thread1
// withObject:nil waitUntilDone:YES];
// wait为YES需要等待主线程操作,NO子线程无需等待
// //这里指定为某个线程
// [self performSelectorInBackground:@selector(threadRun) withObject:nil];
//这里指定为后台线程
NSThread的一些属性

简单例子,售票处理
假设我们需要卖一百张电影票,我们在售票处同时开了三个窗口售票
{
// 线程同步问题:
NSThread *firstThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
firstThread.name = @"thread1";
NSThread *secondThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
secondThread.name = @"thread2";
NSThread *thirdThread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
thirdThread.name=@"thread3";
[firstThread start];
[secondThread start];
[thirdThread start];
[NSThread currentThread];
// while(1) {
// NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket:) object:nil];
// [thread start];
// }
}
- (void)sellTicket:(NSThread*) thread {
while (self.ticketsCount > 0) {
NSThread *thread = [NSThread currentThread];// 获取当前线程
[NSThread sleepForTimeInterval:2];
self.ticketsCount -- ;
NSLog(@"当前线程:%@\n剩余票数为:%d ",thread.name, self.ticketsCount);
}
}
看一下运行结果,发现数据会混乱,这是因为我们没有实现线程同步,造成了资源竞争。
下面我们可以实现线程同步:
- 第一种方式
@synchronized(对象)关键字也就是互斥锁,在新的线程访问时,如果发现其他线程正在执行锁定的代码,新线程进入休眠.
- (void)sellTicket:(NSThread*) thread {
while (self.ticketsCount > 0) {
@synchronized(self) {
NSThread *thread = [NSThread currentThread];
[NSThread sleepForTimeInterval:2];
self.ticketsCount -- ;
NSLog(@"当前线程:%@\n剩余票数为:%d ",thread.name, self.ticketsCount);
}
}
}
- 还可以使用NSLock
NSLock 是 Cocoa 提供给我们最基本的锁对象,也是经常使用的,除 lock 和 unlock 方法外,NSLock 还提供了 tryLock 和 lockBeforeDate: 两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),并不会阻塞线程,直接返回 NO。lockBeforeDate: 方法会在所指定 Date 之前尝试加锁,如果在指定时间之前都不能加锁,则返回 NO。
self.threadLock = [[NSLock alloc]init];
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];
}
边栏推荐
- Difference between idea open and import project
- MySQL learning notes: JSON nested array query
- 对象存储Minio使用教程
- Multivalued mapping: arraylistmultimap and hashmultimap
- Visit the swagger times unable to infer base url
- Reasons why Chinese comments cannot be written in XML
- Artalk | how to build a domestic hyperfusion evolutionary base with minimum investment?
- Demand and Prospect of 3D GIS Industry
- 潮玩力真火力!年轻人第一台巨幕影院?酷开电视Max 86“庞然来袭
- js顶部图标菜单点击切换背景色js特效
猜你喜欢

HQChart钉钉小程序教程1-创建K线图

單片機通信數據延遲問題排查

B_ QuRT_ User_ Guide(17)

Correct posture of cocoscreator's native secondary development

canvas+svg线条粒子动画网页背景

js顶部图标菜单点击切换背景色js特效

Chapter VII introduction to common protocols (1)

Go language advantages and learning Roadmap

Configuring the command line compiled environment -msvc

Log4j:error category option "1" not a decimal integer
随机推荐
HikariPool-1 - Shutdown initiated... HikariPool-1 - Shutdown completed.
Multivalued mapping: arraylistmultimap and hashmultimap
ThoughtWorks.QRCode功能齐全的生成器
音乐正版率关键数据缺失,网易云音乐IPO胜算几何?
Pyqt5:slider slider control
Visit the swagger times unable to infer base url
PostgreSQL source code learning (18) -- mvcc ③ - creating (obtaining) snapshots
Help you distinguish GNU, GCC, GCC and G++
Array full permutation
The solution of invalid @data annotation in idea2018
PostgreSQL source code learning (22) - fault recovery ③ - transaction log registration
Vocabulary Construction -- code completion fast food tutorial (3) - word segmentation
词汇表的构建——代码补全快餐教程(3)-分词
文件合成器
ArTalk | 如何用最小投入,构建国产超融合进化底座?
B_ QuRT_ User_ Guide(17)
Basic use of sonarqube platform
Error in Solr access: error initializing queryelevationcomponent
Pyqt5: basic usage of label control
多线程交替输出AB