首页 > 其他分享 >帮你快速理解同步 ,异步,并发/并行,串行

帮你快速理解同步 ,异步,并发/并行,串行

时间:2023-02-05 21:06:33浏览次数:59  
标签:异步 12 14 16 NSLog 并发 任务 串行 gcd


同步:多个任务情况下,一个任务A执行结束,才可以执行另一个任务B。只存在一个线程。

异步:多个任务情况下,一个任务A正在执行,同时可以执行另一个任务B。任务B不用等待任务A结束才执行。存在多条线程。

帮你快速理解同步 ,异步,并发/并行,串行_并行并发

帮你快速理解同步 ,异步,并发/并行,串行_异步任务_02

接下来分析一下并行/并发,串行。很多人大概会混淆这些概念。

帮你快速理解同步 ,异步,并发/并行,串行_并行并发_03

帮你快速理解同步 ,异步,并发/并行,串行_异步_04

并发和并行其实是异步线程实现的两种形式。并行其实是真正的异步,多核CUP可以同时开启多条线程供多个任务同时执行,互补干扰,如上图的并行,其实和异步图例一样。但是并发就不一样了,是一个伪异步。在单核CUP中只能有一条线程,但是又想执行多个任务。这个时候,只能在一条线程上不停的切换任务,比如任务A执行了20%,任务A停下里,线程让给任务B,任务执行了30%停下,再让任务A执行。这样我们用的时候,由于CUP处理速度快,你看起来好像是同时执行,其实不是的,同一时间只会执行单个任务。

那么串行是什么呢,它是同步线程的实现方式,就是任务A执行结束才能开始执行B,单个线程只能执行一个任务,就如单行道只能行驶一辆车。

恩,到这里大家应该可以理解同步,异步,并行/并发,串行的概念了把~

【并发编程包指在同一时间执行多个任务。又包含并行,和并发。并发不一定并行,但并行一定并发 】


  • 同步任务,使用dispatch_sync将任务加入队列。将同步任务加入串行队列,会顺序执行,一般不这样做并且在一个任务未结束时调起其它同步任务会死锁。将同步任务加入并行队列,会顺序执行,但是也没什么意义。
  • 异步任务,使用dispatch_async将任务加入队列。将异步任务加入串行队列,会顺序执行,并且不会出现死锁问题。将异步任务加入并行队列,会并行执行多个任务,这也是我们最常用的一种方式。
//同步任务加入串行队列
NSLog(@"%@",[NSThread mainThread]);
dispatch_queue_t queue = dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"同步任务1");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_sync(queue, ^{
NSLog(@"同步任务2");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_sync(queue, ^{
NSLog(@"同步任务3");
NSLog(@"%@",[NSThread mainThread]);
});
2016-12-16 14:28:31.959 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
2016-12-16 14:28:31.959 gcd测试[17007:717093] 同步任务1
2016-12-16 14:28:31.959 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
2016-12-16 14:28:31.959 gcd测试[17007:717093] 同步任务2
2016-12-16 14:28:31.960 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
2016-12-16 14:28:31.960 gcd测试[17007:717093] 同步任务3
2016-12-16 14:28:31.960 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
注意点:
需要注意死锁问题,如果在上面的同步任务二中调用其他同步任务会死锁:
dispatch_sync(queue, ^{
NSLog(@"同步任务2");
NSLog(@"%@",[NSThread mainThread]);
dispatch_sync(queue, ^{
NSLog(@"同步任务4");
NSLog(@"%@",[NSThread mainThread]);
});
});
因为任务4会在任务3中执行,然而串行队列一次只能执行一个任务,造成任务4等待任务3结束才能执行,然而任务3结束不了,因为任务4卡住了任务3执行,从而相互等待,造成死锁。

//同步任务加入并行队列
NSLog(@"%@",[NSThread mainThread]);
dispatch_queue_t queue2 = dispatch_queue_create("concertqueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue2, ^{
NSLog(@"同步任务1");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_sync(queue2, ^{
NSLog(@"同步任务2");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_sync(queue2, ^{
NSLog(@"同步任务3");
NSLog(@"%@",[NSThread mainThread]);
});
2016-12-16 14:29:15.219 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
2016-12-16 14:29:15.219 gcd测试[17027:724193] 同步任务1
2016-12-16 14:29:15.219 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
2016-12-16 14:29:15.220 gcd测试[17027:724193] 同步任务2
2016-12-16 14:29:15.220 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
2016-12-16 14:29:15.220 gcd测试[17027:724193] 同步任务3
2016-12-16 14:29:15.220 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}

//异步任务加入串行队列
NSLog(@"%@",[NSThread mainThread]);
dispatch_queue_t queue3 = dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue3, ^{
NSLog(@"异步任务1");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_async(queue3, ^{
NSLog(@"异步任务2");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_async(queue3, ^{
NSLog(@"异步任务3");
NSLog(@"%@",[NSThread mainThread]);
});
2016-12-16 14:30:36.040 gcd测试[17059:737939] <NSThread: 0x610000077980>{number = 1, name = main}
2016-12-16 14:30:38.733 gcd测试[17059:738034] 异步任务1
2016-12-16 14:30:38.734 gcd测试[17059:738034] <NSThread: 0x610000077980>{number = 1, name = (null)}
2016-12-16 14:30:38.734 gcd测试[17059:738034] 异步任务2
2016-12-16 14:30:38.734 gcd测试[17059:738034] <NSThread: 0x610000077980>{number = 1, name = (null)}
2016-12-16 14:30:38.734 gcd测试[17059:738034] 异步任务3
2016-12-16 14:30:38.734 gcd测试[17059:738034] <NSThread: 0x610000077980>{number = 1, name = (null)}

//异步任务加入并行队列
NSLog(@"%@",[NSThread mainThread]);
dispatch_queue_t queue4 = dispatch_queue_create("concertqueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue4, ^{
NSLog(@"异步任务1");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_async(queue4, ^{
NSLog(@"异步任务2");
NSLog(@"%@",[NSThread mainThread]);
});
dispatch_async(queue4, ^{
NSLog(@"异步任务3");
NSLog(@"%@",[NSThread mainThread]);
});
2016-12-16 14:25:54.894 gcd测试[16925:690820] <NSThread: 0x6100000696c0>{number = 1, name = main}
2016-12-16 14:25:58.328 gcd测试[16925:690954] 异步任务1
2016-12-16 14:26:01.805 gcd测试[16925:690959] 异步任务3
2016-12-16 14:26:02.703 gcd测试[16925:690954] <NSThread: 0x6100000696c0>{number = 1, name = (null)}
2016-12-16 14:26:02.703 gcd测试[16925:690975] 异步任务2
2016-12-16 14:26:02.703 gcd测试[16925:690959] <NSThread: 0x6100000696c0>{number = 1, name = (null)}
2016-12-16 14:26:02.704 gcd测试[16925:690975] <NSThread: 0x6100000696c0>{number = 1, name = (null)}


标签:异步,12,14,16,NSLog,并发,任务,串行,gcd
From: https://blog.51cto.com/u_15952281/6038410

相关文章

  • Java多线程并发06—CAS、AQS
    CAS(CompareAndSwap/Set)概念CAS函数,是比较并交换函数,它是原子操作函数。原理CAS是基于乐观锁的原理进行操作的。它总是认为自己可以成功完成操作。当多个线程同时使用CAS......
  • JUC 常用 4 大并发工具类
    什么是JUC?JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些定义类,该包的位置位于java下面的rt.jar包下面。4大常用并发工具类CountDownLatchC......
  • 探秘多线程-闭锁、栅栏与异步编排
    无论是项目开发还是开源代码阅读,多线程都是不可或缺的一个重要知识点,基于这个考量,于是总结出本篇文章,讨论闭锁(CountDownLatch)、栅栏(CyclicBarrier)与异步编排(CompletableF......
  • Go sync并发工具包
    简介在Java中提供Sychronized关键字提供独占锁,Lock类提供读写锁。在sync包中实现的功能也是与锁相关,包中主要包含的有:sync.Map:并发安全mapsync.Mutex:锁sync.RWMutex:......
  • Java多线程并发04—线程池的合理使用
    为什么使用线程池?线程池做的工作主要是控制运行的线程的数量。线程池的种类Java中常用的线程池主要有四种:newCachedThreadPool、newFixedThreadPool、newScheduledThreadPo......
  • Java多线程并发05-锁说明
    根据锁的各种特性,可将锁分为以下几类:乐观锁/悲观锁独享锁(互斥锁)/共享锁(读写锁)可重入锁公平锁/非公平锁分段锁偏向锁/轻量级锁/重量级锁自旋锁乐观锁/悲观锁乐观锁与悲观锁并......
  • GO 并发
    简介Go语言支持并发,我们只需要通过go关键字来开启goroutine即可。goroutine是轻量级线程也有叫用户级线程,协程的,goroutine的调度是由Golang运行时进行......
  • 通过一个示例形象地理解C# async await 非并行异步、并行异步、并行异步的并发量控制
    前言接上一篇通过一个示例形象地理解C#asyncawait异步我在.NET与大数据中吐槽前同事在双层循环体中(肯定是单线程了)频繁请求es,导致接口的总耗时很长。这不能怪前同......
  • Python 异步: 什么是事件循环 ?(6)
    asyncio程序的核心是事件循环。在本节中,我们将花点时间看一下asyncio事件循环。1.什么是Asyncio事件循环事件循环是用于在单个线程中执行协程的环境。事件循环是异......
  • Java多线程并发03—线程上下文,线程调度
    多任务系统往往需要同时执行多道作业。作业数往往大于机器的CPU数,然而一颗CPU同时只能执行一项任务,如何让用户感觉这些任务正在同时进行呢?操作系统的设计者巧妙地利......