创建线程介绍及 GCD 简单使用
2016-05-28 15:58
411 查看
将耗时操作放到线程中进行:
1、NSThread
2、pthread
GCD:
队列:把任务放到队列里面,队列先进先出的原则,
串行队列:顺序,一个一个执行(必须一个任务执行完了,才能从队列里面取出下一个任务)
并发队列:同时,同时执行很多个任务(可以同时取出很多个任务,只要有线程去执行)
同步sync:不会开新线程
异步async:会开新线程,多线程的代名词
串行队列同步执行:不开线程,在原来线程里面一个一个顺序执行
串行队列异步执行:开一条线程,在这个新线程里面一个一个顺序执行
并发队列异步执行:开多个线程,并发执行(不一定是一个一个)执行
并发队列同步执行:不开线程,在原来线程里面一个一个顺序执行
总结:1. 开不开线程,由执行任务方法决定,同步不开线程,异步肯定开线程;
2. 开多少线程,由队列决定,串行 最多 开一个线程, 并发可以开多个线程。 具体开多少个,有GCD底层决定。
1、NSThread
// [NSThread currentThread] 获得当前线程,在开发中经常打印。 所有多线程技术都能使用这个方法 // number == 1 主线程 // number != 1 其他线程,子线程, 次线程 // 将耗时的操作放到子线程执行 // 会开辟一个子线程,并且在子线程执行longTimeOperation方法,后面传递参数 [self performSelectorInBackground:@selector(longTimeOperation) withObject:nil]; // 创建线程方式1 - (void)test1 { // 实例化一个线程对像 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; // 让线程开始工作,启动线程, 在新开的线程执行run方法 [thread start]; } // 创建线程方式2 - (void)test2 { NSLog(@"---%@", [NSThread currentThread]); [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"hello"]; NSLog(@"test2 --- %@", [NSThread currentThread]); } // 创建线程方式3 - (void)test3 { // “隐式”创建线程方式 [self performSelectorInBackground:@selector(run:) withObject:@"cz"]; }
2、pthread
// 声明一个线程变量 pthread_t threadId; /* 参数: 1. 要开的线程的变量 2. 线程的属性 3. 要在这个子线程执行的函数(任务) 4. 这个函数(任务)需要传递的参数 */ // pthread_create(,, , <#void *restrict#>) id str = @"hello"; // id需要转成void *,在ARC里,需要使用__bridge 进行桥联 // 1. 这里只是临时把str对象专程void *在这里临时使用。 不改变这个对象(str)的所有权。 // 2. 把对象的所有权交出去,在这个函数把str转成void * // 如果使用MRC,这里不需要桥联,可以直接设置这个参数 // ARC自动内存管理,本质是编译器特性。是在程序编译的时候,编译器帮我们在合适的地方添加retain,release,autorelease。 pthread_create(&threadId, NULL, run, (__bridge void *)(str)); // 函数 void *run(void *param) { NSString *str = (__bridge NSString *)(param); // 耗时操作放在这里执行 for (int i = 0; i < 20000; i++) { NSLog(@"%@----%@", [NSThread currentThread], str); } return NULL; }
GCD:
队列:把任务放到队列里面,队列先进先出的原则,
串行队列:顺序,一个一个执行(必须一个任务执行完了,才能从队列里面取出下一个任务)
并发队列:同时,同时执行很多个任务(可以同时取出很多个任务,只要有线程去执行)
同步sync:不会开新线程
异步async:会开新线程,多线程的代名词
串行队列同步执行:不开线程,在原来线程里面一个一个顺序执行
串行队列异步执行:开一条线程,在这个新线程里面一个一个顺序执行
并发队列异步执行:开多个线程,并发执行(不一定是一个一个)执行
并发队列同步执行:不开线程,在原来线程里面一个一个顺序执行
/** 串行队列:顺序,一个一个执行 同步任务:不会开辟新线程,是在当前线程执行 结果:不开新线程,在当前线程顺序执行 dispatch : 调度,GCD里面函数,都是以dispatch开头的 */ // 1. 创建一个串行队列 //参数:1. 队列标签 2. 队列的属性 dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL); // 2. 同步执行任务 // 一般只要使用”同步“执行,串行队列对添加的同步任务,会立马执行 dispatch_sync(queue, ^{ NSLog(@"%@", [NSThread currentThread]); });
/** 串行队列:一个一个执行 异步执行:肯定会开新线程,在新线程执行 结果:只会开一个线程,而且所有任务都在这个新的线程里面执行 */ // 1. 串行队列 // 下面两种写法是一样的 // dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue = dispatch_queue_create("itcast", NULL); // 2. 异步执行 for (int i = 0; i < 10; i++) { dispatch_async(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); }
/** 并发队列:可以同时执行多个任务 同步任务:不会开辟新线程,是在当前线程执行 结果:不开新线程,顺序一个一个执行。 */ //1. 并行队列 dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT); // 2. 同步执行任务 for (int i = 0; i < 10; i++) { dispatch_sync(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); }
/** 并发队列:可以同时执行多个任务 异步执行:肯定会开新线程,在新线程执行 结果:会开很多个线程,同时执行 */ //1. 并行队列 dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT); // 2. 异步执行任务 for (int i = 0; i < 10; i++) { dispatch_async(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); }
总结:1. 开不开线程,由执行任务方法决定,同步不开线程,异步肯定开线程;
2. 开多少线程,由队列决定,串行 最多 开一个线程, 并发可以开多个线程。 具体开多少个,有GCD底层决定。
相关文章推荐
- C#线程间不能调用剪切板的解决方法
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- 简单对比C#程序中的单线程与多线程设计
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法
- C#实现线程安全的简易日志记录方法
- C#中线程同步对象的方法分析
- ASP.NET线程相关配置
- 浅析linux环境下一个进程最多能有多少个线程
- 再谈JavaScript线程
- C#实现终止正在执行的线程
- Java线程编程中的主线程讲解