一、多线程概述
1、进程,线程
进程:进程是指在系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内,例如同时打开QQ、Xcode,系统就会分别启动2个进程。
线程:1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行比如使用酷狗播放音乐、使用迅雷下载电影,都需要在线程中执行。
2、单线程、多线程 以及单线程和多线程的区别
二、iOS多线程实现种类
1、pthread
2、NSThread
3、NSOperation
4、GCD
5、NSObject
三、iOS多线程实现种类的具体实现
1、pthread
(1)代码示例:
“//// ViewController.m// 10-多线程的简单认识//// Created by lanou on 16/7/1.// Copyright © 2016年 Huangyu. All rights reserved.//#import "ViewController.h"#import@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
void *run(void *papa)
{
for (NSInteger i = 0 ; i < 50000; i++) {
NSLog(@"%lu", i);
}
return NULL;
}
- (IBAction)btnAction:(id)sender {
//pthread的简单认识
pthread_t pthread;
//p1 : 线程指针
//p2 : 线程的一些属性
//p3 : 函数指针 用于执行方法
//p4 : 线程中的传值
pthread_create(&pthread, NULL, run, NULL);
}”
(2)打印效果:
2、NSThread
(1)代码示例:
“//
// ViewController.m
// 06-NSThread
//
// Created by lanou on 16/6/30.
// Copyright © 2016年 Huangyu. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
//定义线程对象01
@property (nonatomic, strong) NSThread *thread01;
//定义线程对象02
@property (nonatomic, strong) NSThread *thread02;
//定义一个计数器, integer
@property (nonatomic, assign) NSInteger counter;
//定义一个线程锁对象
@property (nonatomic, strong) NSLock *lock;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
for (int i = 0; i < 3; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(120, 150 + 80 * i, 80, 40);
[btn addTarget:self action:@selector(pressBtn:) forControlEvents:UIControlEventTouchUpInside];
btn.tag = 101 + i;
if (i == 0) {
[btn setTitle:@"启动线程" forState:(UIControlStateNormal)];
} else if(i == 1)
{
[btn setTitle:@"启动线程01" forState:(UIControlStateNormal)];
}
else if (i == 2)
{
[btn setTitle:@"启动线程02" forState:(UIControlStateNormal)];
}
[self.view addSubview:btn];
}
//加锁操作
_lock = [[NSLock alloc] init];
}
-(void)pressBtn:(UIButton *) btn
{
//执行函数01
if (btn.tag == 101) {
NSLog(@"按钮1按下!");
//创建一个线程对象
//P1:线程对象运行函数的拥有者
//p2:线程处理函数
//p3:线程参数
NSThread *newT = [[NSThread alloc] initWithTarget:self selector:@selector(actNew:) object:nil];
//启动并且运行线程
[newT start];
}
else if (btn.tag == 102)
{
NSLog(@"按钮2按下!");
//创建并且启动线程
[NSThread detachNewThreadSelector:@selector(actT1) toTarget:self withObject:nil];
}
else if (btn.tag == 103)
{
NSLog(@"按钮3按下!");
_thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(actT2) object:nil];
[_thread02 start];
}
}
-(void)actT1
{
int i = 0;
while (true) {
// NSLog(@"T1 act !");
i++;
if (i >= 10001) {
break;
}
[_lock lock];
_counter ++;
[_lock unlock];
NSLog(@"c1 = %ld", _counter);
}
NSLog(@"c1 final = %ld", _counter);
}
-(void)actT2
{
int i = 0;
while (true) {
// NSLog(@"T2 act !");
i++;
if (i >= 10001) {
break;
}
//确保加法操作安全性
[_lock lock];
_counter ++;
[_lock unlock];
NSLog(@"c2 = %ld", _counter);
}
NSLog(@"c2 final = %ld", _counter);
}
//P1:线程对像本身
-(void)actNew:(NSThread *) thread
{
int i = 0;
while (true) {
i++;
NSLog(@"i = %d", i);
}
}”
(2)运行效果:
3、NSOperation
(1)代码示例:
“//
// ViewController.m
// 10 - 03NSOperation
//
// Created by lanou on 16/7/1.
// Copyright © 2016年 Huangyu. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
//NSOperation是一个抽象的类,一般不直接使用它, 而是使用他的子类NSInvocationOperation 还有NSBlockOperation
-(void)createNSOperation
{
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction1) object:nil];
// [operation1 start];
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction2) object:nil];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 20; i < 30; i++) {
NSLog(@"%d", i);
}
}];
//操作队列
//目的:是将我们的任务放在一个队列中执行
//任务:任务执行在主线程还是子线程全都由我们的队列来决定
//加入队列
//mainQueue 代表主队列
//如果是 alloc] init 就代表其他队列
// NSOperationQueue *queue = [NSOperationQueue mainQueue];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//先加的先执行 后加的后执行 但是执行的时间不一定, 可能后执行的比先执行的先执行完
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
}
-(void)operationAction1
{
// NSLog(@"%d", [NSThread isMainThread]);
for (int i = 0; i < 10; i++) {
NSLog(@"%d", i);
}
}
-(void)operationAction2
{
// NSLog(@"%d", [NSThread isMainThread]);
for (int i = 10; i < 20; i++) {
NSLog(@"%d", i);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self createNSOperation];
}”
(2)打印效果:
4、GCD
(1)代码示例:
“//// ViewController.m// 10-4-GCD的基本使用//// Created by lanou on 16/7/1.// Copyright © 2016年 Huangyu. All rights reserved.//#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. dispatch_queue_t queue = dispatch_queue_create("aaa", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); dispatch_sync(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); }); }-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
//错误的演示
// [self createScynMain];
// [self createAcynMain];
// [self createSyncSerial];
// [self createAsyncSerial];
// [self createSyncConcurrent];
// [self createAsycConcurrent];
}
//伟大的中枢调动器 GCD
//异步:不在一个线程执行
//同步:在同一个线程执行
// 串行:串在一起执行
// 并行:一起执行
/*
同步 + 主队列
*/
-(void)createScynMain
{
// 获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//将任务加到队列中
//P1:放队列中
//p2:要执行的任务
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}
/*
异步 + 主队列:不开辟线程, 就在主线程执行
*/
-(void)createAcynMain
{
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}
/*
同步 + 串行队列:不具备开启线程的能力, 在当前线程完成任务
*/
-(void)createSyncSerial
{
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("aaa.com.queue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}
/*
异步 + 串行队列:具备开启线程的能力, 但是任务是串行的, 执行完一个才去执行下一个
*/
-(void)createAsyncSerial
{
dispatch_queue_t queue = dispatch_queue_create("aaa.com", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}
/*
同步 + 并发队列:不具备开启线程的能力 , 并发的功能也就废了
*/
-(void)createSyncConcurrent
{
//p1: 对列的名字
//p2: 类型
//我们自己创建的并发队列
// dispatch_queue_t queue = dispatch_queue_create("sbs.nb.com", DISPATCH_QUEUE_CONCURRENT);
//创建一个并发队列
//获得全局的并发队列
//p1: 为一个优先级 默认的就行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}
/*
最经常使用的
异步 + 并发队列:具备开启子线程的能力 , 并且并发执行任务
*/
-(void)createAsycConcurrent
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}”
(2)打印效果:
5、NSObject
三、总结