写在前面吧:
上图是下半年的学习计划进度脑图,默默坚持~~
这篇文 只能算是一个观看笔记,感谢不死鸟大佬的教学,看完受益良多
进程
五态模型线程
- 线程是进程的基本执行单元
- 进程的所有任务都是在线程中执行
多线程
- 网络请求
- 图片加载
- 文件处理
- 数据存储
- 任务执行等
串行
串行耗时并行
并行多线程实现原理
单核多核
多线程优缺点
优点:
- 简化了编程模型
- 更加轻量级
- 提高执行效率
- 提高资源利用率
缺点:
- 增加了程序设计的复杂性
- 占用内存空间
- 增加了CPU的调度开销
多线程实现技术方案
pThread[基于C,移植性强]
- 代码:
///pThread
- (void)setupThreadWithpThread
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 100, 30);
[btn setTitle:@"pThread" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(clickPThread) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)clickPThread
{
NSLog(@"我在主线程中执行");
pthread_t pthread;
pthread_create(&pthread, NULL, run, NULL);
}
void *run(void *data)
{
NSLog(@"我在子线程中执行");
for (int i=1; i<10; i++) {
NSLog(@"%d",i);
sleep(1);
}
return NULL;
}
- 控制台:
2018-07-05 16:12:14.838406+0800 TestThread[4503:324104] 我在主线程中执行
2018-07-05 16:12:14.839701+0800 TestThread[4503:324183] 我在子线程中执行
2018-07-05 16:12:14.841281+0800 TestThread[4503:324183] 1
2018-07-05 16:12:15.844024+0800 TestThread[4503:324183] 2
2018-07-05 16:12:16.845006+0800 TestThread[4503:324183] 3
2018-07-05 16:12:17.845463+0800 TestThread[4503:324183] 4
2018-07-05 16:12:18.848984+0800 TestThread[4503:324183] 5
2018-07-05 16:12:19.853491+0800 TestThread[4503:324183] 6
2018-07-05 16:12:20.857345+0800 TestThread[4503:324183] 7
2018-07-05 16:12:21.859202+0800 TestThread[4503:324183] 8
2018-07-05 16:12:22.860372+0800 TestThread[4503:324183] 9
NSThread
- 通过
alloc init
的方式创建并执行线程,可控制线程name
等属性
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(runThread1) object:nil];
[thread1 start];
- 通过detachNewThreadSelector 方式创建并执行线程
[NSThread detachNewThreadSelector:@selector(runThread1) toTarget:self withObject:nil];
- 通过detachNewThreadSelector 方式创建并执行线程
[NSThread detachNewThreadSelector:@selector(runThread1) toTarget:self withObject:nil];
- 代码:
- (void)setupThreadWithNSThread
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 150, 100, 30);
[btn setTitle:@"NSThread" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(clickNSThread) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)clickNSThread
{
NSLog(@"我在主线程中执行");
[self performSelectorInBackground:@selector(runThread1) withObject:nil];
}
- (void)runThread1
{
NSLog(@"我在子线程中执行");
for (int i=1; i<10; i++) {
NSLog(@"%d",i);
sleep(1);
if (i == 9) {
[self performSelectorOnMainThread:@selector(runMainThread) withObject:nil waitUntilDone:YES];
}
}
}
- (void)runMainThread
{
NSLog(@"回到线程中执行");
}
- 控制台:
2018-07-05 16:34:08.496514+0800 TestThread[4718:338296] 我在主线程中执行
2018-07-05 16:34:08.499321+0800 TestThread[4718:338376] 我在子线程中执行
2018-07-05 16:34:08.500084+0800 TestThread[4718:338376] 1
2018-07-05 16:34:09.575477+0800 TestThread[4718:338376] 2
2018-07-05 16:34:10.576032+0800 TestThread[4718:338376] 3
2018-07-05 16:34:11.648309+0800 TestThread[4718:338376] 4
2018-07-05 16:34:12.721992+0800 TestThread[4718:338376] 5
2018-07-05 16:34:13.794289+0800 TestThread[4718:338376] 6
2018-07-05 16:34:14.869460+0800 TestThread[4718:338376] 7
2018-07-05 16:34:15.944381+0800 TestThread[4718:338376] 8
2018-07-05 16:34:17.018836+0800 TestThread[4718:338376] 9
2018-07-05 16:34:18.094780+0800 TestThread[4718:338296] 回到线程中执行
GCD
注意的思考点:
1->同步
&异步
2->串行
&并行
3->dispatch_get_main_queue()
&dispatch_get_global_queue()
4->dispatch_group_enter
&dispatch_group_leave
<-简单应用->
- 代码:
- (void)setupThreadWithGCD
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 200, 100, 30);
[btn setTitle:@"GCD" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(clickGCD) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)clickGCD
{
NSLog(@"执行GCD");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//执行耗时任务
NSLog(@"执行耗时任务 task1");
[NSThread sleepForTimeInterval:3];
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程,刷新UI
NSLog(@"回到主线程刷新UI");
});
});
}
- 控制台:
2018-07-05 17:47:25.353341+0800 TestThread[5365:385948] 执行GCD
2018-07-05 17:47:25.353779+0800 TestThread[5365:386006] 执行耗时任务 task1
2018-07-05 17:47:28.359846+0800 TestThread[5365:385948] 回到主线程刷新UI
<-按顺序执行->
- 代码:
/*
* 执行--结束的顺序
* DISPATCH_QUEUE_PRIORITY_LOW
* DISPATCH_QUEUE_PRIORITY_HIGH
* DISPATCH_QUEUE_PRIORITY_DEFAULT
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSLog(@"执行耗时任务 task1");
[NSThread sleepForTimeInterval:2];
NSLog(@"结束耗时任务 task1");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"执行耗时任务 task2");
[NSThread sleepForTimeInterval:2];
NSLog(@"结束耗时任务 task2");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"执行耗时任务 task3");
[NSThread sleepForTimeInterval:2];
NSLog(@"结束耗时任务 task3");
});
- 控制台:
2018-07-06 10:15:37.850583+0800 TestThread[951:33839] 执行GCD
2018-07-06 10:15:37.850954+0800 TestThread[951:33906] 执行耗时任务 task2
2018-07-06 10:15:37.850963+0800 TestThread[951:33905] 执行耗时任务 task3
2018-07-06 10:15:37.850989+0800 TestThread[951:33908] 执行耗时任务 task1
2018-07-06 10:15:39.853563+0800 TestThread[951:33906] 结束耗时任务 task2
2018-07-06 10:15:39.853581+0800 TestThread[951:33905] 结束耗时任务 task3
2018-07-06 10:15:39.895970+0800 TestThread[951:33908] 结束耗时任务 task1
NSOperation[基类]``[线程池]``[最大并发数]
使用的两种方式:
1-->NSInvocationOperation
2-->NSBlockOperation
- 相关概念:
1、NSOperationQueue:
a. addOperation
b. setMaxConcurrentOperationCount
2、状态:
ready
、cancelled
、executing
、finished
、asynchronous
3、依赖:
addDependency
- 代码:
- (void)setupThreadWithNSOperation
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 350, 150, 30);
[btn setTitle:@"NSOperation" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(clickNSOperation) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)clickNSOperation
{
NSLog(@"我是主线程");
/*
NSBlockOperation *blockOper = [NSBlockOperation blockOperationWithBlock:^{
for (int i=0; i < 3; i++) {
NSLog(@"invocation--%d",i);
[NSThread sleepForTimeInterval:1];
}
}];
[blockOper start];
*/
/*
NSInvocationOperation * invocationOper = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction) object:nil];
//start 方式启用,会是在当前程执行`[同步-非并发]`
[invocationOper start];
*/
//开启子线程,则会阻塞子线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSInvocationOperation * invocationOper = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction) object:nil];
[invocationOper start];
});
}
- (void)invocationAction
{
for (int i=0; i < 3; i++) {
NSLog(@"invocation--%d",i);
[NSThread sleepForTimeInterval:1];
}
}
- 控制台:
2018-07-06 14:20:10.971880+0800 TestThread[2760:150878] 我是主线程
2018-07-06 14:20:10.973186+0800 TestThread[2760:150932] invocation--0
2018-07-06 14:20:11.977305+0800 TestThread[2760:150932] invocation--1
2018-07-06 14:20:12.981491+0800 TestThread[2760:150932] invocation--2
结束语
再次说明,这只是一篇笔记,要想真正用好多线程,短期内估计是不行,需要多练习了,共勉之~
网友评论