iOS多线程之:从代码中体会队列、进程线程、同步异步、任务的概念

多线程的概念很多,其中还包含了嵌套使用,就像三角函数公式一样,巨多;但在代码的世界中,概念并不是泛泛的、抽象的,多敲敲代码就明白其中的奥义

本文仅使用GCD的几个基础API来从中体会这些概念

1.概念简介

在从代码中分析之前,还是要简单的描述一下,名词的基本概念,有个印象便可直接去代码中体会

  • 进程线程

进程:一个在内存中运行的应用程序。如Windows系统中的.exe,iPhone上的在运行的某个APP
每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,且至少有一个常驻线程,在iOS中这个必须常驻的唯一的线程叫做主线程

线程: 进程要做事(任务)时,要把做的事交给线程去处理,线程负责当前进程中程序(要处理的任务)的执行,那段要执行的代码,也就是说要处理的事,叫任务

  • 任务

任务: 交给线程做的事,是一行或者多行程序,在GCD中以block的形式存在

  • 同步异步
    能不能开启新的线程

同步:不具备开启线程的能力,在当前线程中执行;
同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。

异步:具备开启线程的能力,在新开启的线程中执行
异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务

  • 队列
    任务的执行方式

并行:可以多个任务同时执行

串行:一个任务执行完毕,在执行下一个任务

2.多次调用体会

2.1:组合分析
区别\分析 并发队列 串行队列 主队列
sync 同步不能开启新的线程,所以尽管是并发队列,但同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。任务的执行效果如:串行执行任务 同步不能开启新的线程,且串行队列,执行效果为:串行执行任务 在执行当前主线程任务的过程中,同步主队列到主线程上,因为都是主线程上的任务,添加的任务需要等当前任务执行完毕,当前任务需要等添加的任务执行完毕,所以锁死
async 异步开启新线程,并发有多个线程支撑,任务执行效果:并发执行任务 异步可以开启多条线程,但因为是串行队列,一个任务执行完毕才执行下一个,所以开启一条新线程足矣,执行效果为:串行执行任务 当前任务和添加到主队列中的任务都在主线中执行,但是异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务,所以会先执行完当前任务再执行添加的任务
区别\结论 并发队列 串行队列 主队列
sync 未开启新的线程,串行执行任务 未开启新的线程,串行执行任务 死锁
async 开启多条新线程,并发执行任务 开启一条新线程:串行执行任务 没有开启新线程,串行执行任务
2.2:代码体会

一下的打印皆按照顺序打印多次XXXX

2.2.1:同步串行
- (void)viewDidLoad {
   
    [super viewDidLoad];
    
    NSLog(@"%@", [NSThread currentThread]);
    NSLog(@"KAISHI");
    dispatch_queue_t queue = dispatch_queue_create("HD", nil);
    for (int x = 0; x < 10; x++) {
   
        dispatch_sync(queue, ^{
   
            [NSThread sleepForTimeInterval:2];
            NSLog(@"%d -- %@", x, [NSThread currentThread]);
        });
    }
    NSLog(@"JIESHU");
}

输出结果:
2022-07-27 13:55:14.740593+0800 Test[7227:347198] <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:14.740823+0800 Test[7227:347198] KAISHI
2022-07-27 13:55:16.741187+0800 Test[7227:347198] 0 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:18.742611+0800 Test[7227:347198] 1 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:20.744061+0800 Test[7227:347198] 2 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:22.745448+0800 Test[7227:347198] 3 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:24.745874+0800 Test[7227:347198] 4 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:26.747351+0800 Test[7227:347198] 5 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:28.748105+0800 Test[7227:347198] 6 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:30.749498+0800 Test[7227:347198] 7 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:32.750432+0800 Test[7227:347198] 8 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:34.751921+0800 Test[7227:347198] 9 – <_NSMainThread: 0x600001414040>{number = 1, name = main}
2022-07-27 13:55:34.752264+0800 Test[7227:347198] JIESHU

分析:

  • 代码是放在ViewDidLoad中的,所以[NSThread currentThread]是{number = 1, name = main}为主线程重执行任务;
  • sync不开启新的线程,queue是serial为串行队列,需要执行完一个任务再执行一个任务,所以打印时间都相差睡眠的2秒JIESHU在10组同步串行任务之后打印
2.2.2 :同步并行
- (void)viewDidLoad {
   
    [super viewDidLoad];
    
    NSLog(@"%@", [NSThread currentThread]);
    NSLog(@"KAISHI");
    dispatch_queue_t queue = dispatch_queue_create("HD", DISPATCH_QUEUE_CONCURRENT);
    for (int x = 0; x < 10; x++) {
   
        dispatch_sync(queue, ^{
   
            [NSThread sleepForTimeInterval:2];
            NSLog(@"%d -- %@", x, [NSThread currentThread]);
        });
    }
    NSLog(@"JIESHU");
}

打印结果
2022-07-27 14:52:49.304526+0800 Test[7688:381587] <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:52:49.304746+0800 Test[7688:381587] KAISHI
2022-07-27 14:52:51.306111+0800 Test[7688:381587] 0 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:52:53.307739+0800 Test[7688:381587] 1 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:52:55.309328+0800 Test[7688:381587] 2 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:52:57.310813+0800 Test[7688:381587] 3 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:52:59.311261+0800 Test[7688:381587] 4 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:53:01.312800+0800 Test[7688:381587] 5 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name = main}
2022-07-27 14:53:03.314424+0800 Test[7688:381587] 6 – <_NSMainThread: 0x600001e9c9c0>{number = 1, name =

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值