1.使用NSThread实现多线程
1.1.线程的创建
- (void)viewDidLoad {
[super viewDidLoad];
//获取当前主线程
NSThread *current = [NSThread currentThread];
NSLog(@"%@",current);
//获取主线程
NSThread *main = [NSThread mainThread];
NSLog(@"主线程----%@",main);
[self threadCreate1];
}
-(void)threadCreate1{
NSThread *threadA = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"第一种A"];
threadA.name = @"线程A";
[threadA start];
NSThread *threadB = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"第一种B"];
threadB.name = @"线程B";
[threadB start];
}
-(void)run:(NSString *)param{
//获取当前线程
NSThread *current = [NSThread currentThread];
NSLog(@"%@-----%@",current,param);
}
打印出这个
<NSThread: 0x604000261980>{number = 1, name = main}
主线程----<NSThread: 0x604000261980>{number = 1, name = main}
<NSThread: 0x60000046c7c0>{number = 3, name = 线程A}-----第一种A
<NSThread: 0x60000046c4c0>{number = 4, name = 线程B}-----第一种B
还有下面两种创建线程的方式
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"第二种"];
[self performSelectorInBackground:@selector(run:) withObject:@"第三种"];
1.2由多线程引发的一个常见问题 并发
- OC的解决方法 同步锁
确保对象每次只能被一个线程访问 obj代表对象
@synchronized(obj){
//插入被修饰的代码块
}
但是万事有利有弊,这里就好比同步和异步
同步锁就相当于将异步弄成了同步,性能上势必会降低,更加消耗CPU资源,很难把握性能和功能的平衡
尽量使同步锁包括的代码范围小一点
1.3线程间的通信
//这个方法是将指定的方法放在主线程中执行
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
2.使用GCD实现多线程 (Grand Central Dispatch)
GCD核心概念队列和任务
使用 GCD:
- 创建队列
- 将任务的代码块提交给队列
dispatch_queue_t serialQueue;
dispatch_queue_t globalQueue;
- (void)viewDidLoad {
[super viewDidLoad];
//创建串行队列 第一个参数用来表示队列的提示符,可以选择设置或则为NULL 第二个参数设置串行队列还是并行队列
serialQueue = dispatch_queue_create("cn.itcast", DISPATCH_QUEUE_SERIAL);
//获取全局变量 第一个参数用来获取队列的优先级 第二个供以后使用
globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}
//单击“串行同步任务”后执行的行为
- (IBAction)synSerial:(id)sender {
dispatch_sync(serialQueue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"%@--task1--%d",[NSThread currentThread],i);
}
});
dispatch_sync(serialQueue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"%@--task2--%d",[NSThread currentThread],i);
}
});
}
//单击“并行同步任务”后执行的任务
- (IBAction)synConcurrent:(id)sender {
dispatch_sync(globalQueue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"%@--task3--%d",[NSThread currentThread],i);
}
});
dispatch_sync(globalQueue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"%@--task4--%d",[NSThread currentThread],i);
}
});
}
串行同步任务:不会开启新的线程,执行完上一个任务之后,才会开始下一个任务
并行同步任务:不会开启新的线程,执行完上一个任务之后,才会开始下一个任务
结论:用同步的方式不会开启新的线程
dispatch_queue_t serialQueue;
dispatch_queue_t concurrentQueue;
- (void)viewDidLoad {
[super viewDidLoad];
//创建串行队列
serialQueue = dispatch_queue_create("cn.itcast", DISPATCH_QUEUE_SERIAL);
//创建并队列
concurrentQueue = dispatch_queue_create("cn.itcast", DISPATCH_QUEUE_CONCURRENT);
}
//点击“串行异步任务”后执行的任务
- (IBAction)asynSerial:(id)sender {
dispatch_async(serialQueue, ^{
for (int i=0; i<10; i++) {
NSLog(@"%@--task1--%d",[NSThread currentThread],i);
}
});
dispatch_async(serialQueue, ^{
for (int i=0; i<10; i++) {
NSLog(@"%@--task2--%d",[NSThread currentThread],i);
}
});
}
//单击“并行异步任务”后执行的行为
- (IBAction)asynConcurrent:(id)sender {
dispatch_async(concurrentQueue, ^{
for (int i=0; i<10; i++) {
NSLog(@"%@--task3--%d",[NSThread currentThread],i);
}
});
dispatch_async(concurrentQueue, ^{
for (int i=0; i<10; i++) {
NSLog(@"%@--task4--%d",[NSThread currentThread],i);
}
});
}
串行异步任务:开启一个新的线程,执行完上一个任务之后,才会开始下一个任务
并行异步任务:开启两个新的线程,执行的先后顺序也无法控制
注意: 各种队列的执行结果.jpg
网友评论