GCD

作者: wordlesser | 来源:发表于2017-12-06 22:45 被阅读29次

GCD大家用的都比较多,但有时候却搞不太清楚同步异步,并行串行各种组合的应用场景,最近整理了一下。

/*
 总结放在前边,如有不对的地方还请指教
 名词解释:
 同步:不开辟新线程(在当前线程)
 异步:开辟新的线程(在新的线程)
 
 串行:(在同一个线程)有序执行
 并行:(在多个线程)无序执行
 
 
 理解:
 如果没有开辟新的线程,在当前线程中就只能FIFO,所以同步并行实际也还是串行执行的(并行和异步绑定使用才是有效的)
 
 坑:
”串行&异步“或者”异步&串行“感觉是一样的  后来发现 ”异步串行“这样记才更容易理解如下:
 异步串行=开辟新的线程并有序执行(开辟一条新线程有序执行)
 异步并行=开辟新的线程&无序执行(开辟多条新线程无序执行)
 同步串行=不开辟新线程&有序执行(没有新的线程只能在当前线程有序执行)
 同步并行=不开辟新线程&无序执行(没有新的线程只能在当前线程有序执行)
 
 a异步全局队列:
 1.创建多个线程
 2.无序执行
 总结:适用于没有相互依赖关系的网络请求,既单独的网络请求,如:加载一个列表数据
 
 b异步并行队列:(异步全局队列也是并行队列,但是全局队列没有名字不用管理可以直接使用)
 1.创建多个线程
 2.无序执行
 总结:如a
 
 c同步并行队列:
 1.不会创建新的线程
 2.在当前线程FIFO
 总结:没用
 
 
 d异步串行队列:
 1.会创建一条新线程
 2.在新的线程上FIFO
 总结:适用于相互依赖的网络请求,既下一个任务依赖当前任务,如:图片上传完成后才能发布一条内容《可能例子不太恰当,正常操作可能是图片完成后在回调中直接做发布操作》
 
 e同步串行队列:
 1.不会创建新线程
 2.在当前线程上FIFO
 总结:没用
 
 也就是说基本上只有异步操作的时候才需要用到GCD,其他情况实际上都是在当前线程有序执行的
 */

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.globalAsyncQueue()
    }
    
    func globalAsyncQueue() {
        print("异步全局队列")
        //全局队列
        let globalQueue = DispatchQueue.global()
                
        let globalQueueGroup = DispatchGroup()
        for i in 0..<10 {
            globalQueueGroup.enter()
            globalQueue.async(execute: { 
                print("\(Thread.current.description)\(i)")
                globalQueueGroup.leave()
            })
        }
        globalQueueGroup.notify(queue: DispatchQueue.main) { 
            self.concurrentAsyncQueue()
        }
        /*
         异步全局队列:
         1.创建多个线程
         2.无序执行
         */
    }
    
    func concurrentAsyncQueue() {
        print("异步并行队列")
        //并行队列
        let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: DispatchQueue.Attributes.concurrent)
        let concurrentQueueGroup = DispatchGroup()
        for i in 0..<10 {
            concurrentQueueGroup.enter()
            concurrentQueue.async(execute: { 
                print("\(Thread.current.description)\(i)")
                concurrentQueueGroup.leave()
            })
        }
        //任务完成后,通知主线程
        concurrentQueueGroup.notify(queue: DispatchQueue.main) { 
            self.concurrentSyncQueue()
        }
        /*
         异步并行队列:(异步全局队列也是并行队列类似,但是全局队列没有名字不用管理可以直接使用)
         1.创建多个线程
         2.无序执行
         */

    }
    
    func concurrentSyncQueue() {
        print("同步并行队列")
        //并行队列
        let concurrentQueue = DispatchQueue(label: "concurrentSyncQueue", attributes: DispatchQueue.Attributes.concurrent)
        let concurrentQueueGroup = DispatchGroup()
        for i in 0..<10 {
            concurrentQueueGroup.enter()
            concurrentQueue.sync(execute: { 
//                Thread.sleep(forTimeInterval: 0.3)
                print("\(Thread.current.description)\(i)")
                concurrentQueueGroup.leave()
            })
        }
        //任务完成后,通知当前线程
        concurrentQueueGroup.notify(queue: concurrentQueue) { 
            self.serialAsyncQueue()
        }
        /*
         同步并行队列:
         1.不会创建新的线程
         2.在当前线程FIFO
         */
    }


    func serialAsyncQueue() {
        print("异步串行队列")
        //串行队列
        let serialQueue = DispatchQueue(label: "serialQueue")
        let serialQueueGroup = DispatchGroup()
        for i in 0..<10 {
            serialQueueGroup.enter()
            serialQueue.async(execute: { 
                print("\(Thread.current.description)\(i)")
                serialQueueGroup.leave()
            })
        }
        //任务完成后,通知主线程
        serialQueueGroup.notify(queue: DispatchQueue.main) { 
            self.serialSyncQueue()
        }
        /*
         异步串行队列:
         1.会创建一条新线程
         2.在新的线程上FIFO
         */
    }
    
    func serialSyncQueue() {
        print("同步串行队列")
        //串行队列
        let serialQueue = DispatchQueue(label: "serialSyncQueue")
        let serialQueueGroup = DispatchGroup()
        for i in 0..<10 {
            serialQueueGroup.enter()
            serialQueue.sync(execute: { 
//                Thread.sleep(forTimeInterval: 0.3)
                print("\(Thread.current.description)\(i)")
                serialQueueGroup.leave()
            })
        }
        serialQueueGroup.notify(queue: DispatchQueue.main) { 
            self.mainAsyncQueue()
        }
        /*
         同步串行队列:
         1.不会创建新线程
         2.在当前线程上FIFO
         */
    }
    
    func mainAsyncQueue() {
        print("异步主线程队列")
        //串行队列
        let mainQueue = DispatchQueue.main
        let mainQueueGroup = DispatchGroup()
        for i in 0..<10 {
            mainQueueGroup.enter()
            mainQueue.async(execute: { 
                //                Thread.sleep(forTimeInterval: 0.3)
                print("\(Thread.current.description)\(i)")
                mainQueueGroup.leave()
            })
        }
        mainQueueGroup.notify(queue: DispatchQueue.main) { 
            self.mainSyncQueue()
        }
        /*
         异步主线程队列:
         1.因为主线程只有一个,所以不会创建新线程
         2.在主线程上FIFO
         */
    }


    func mainSyncQueue() {
        print("同步主线程队列,会发生crash,线程死锁,想要测试可以注释return")
        //会发生crash,线程死锁
        return
        //串行队列
        let mainQueue = DispatchQueue.main
        let mainQueueGroup = DispatchGroup()
        for i in 0..<10 {
            mainQueueGroup.enter()
            mainQueue.sync(execute: { 
                //                Thread.sleep(forTimeInterval: 0.3)
                print("\(Thread.current.description)\(i)")
                mainQueueGroup.leave()
            })
        }
        mainQueueGroup.notify(queue: DispatchQueue.main) { 
            print("执行完成")
        }
        /*
         同步主线程队列:
         1.不会创建新线程
         2.在当前线程上FIFO
         */
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

相关文章

  • 多线程之GCD

    GCD介绍 1、GCD简介 2、GCD任务和队列 3、GCD 的基本使用 4、GCD 线程间的通信 5、GCD 的...

  • 扩展GCD(求逆元,解同余方程等等)

    首先要知道gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(|a|,|b|)=gcd(b,a%b)...

  • iOS - GCD

    目录 GCD简介 GCD核心概念 GCD队列的使用 GCD的常见面试题 GCD简介 Grand Central D...

  • iOS-多线程:GCD

    GCD 简介 GCD 任务和队列 GCD 的使用步骤 GCD 的基本使用(6种不同组合区别) GCD 线程间的通信...

  • 浅析GCD

    GCD目录: 1. GCD简介 为什么要用GCD呢? GCD可用于多核的并行运算GCD会自动利用更多的CPU内核(...

  • 7.3 多线程-GCD

    多线程-GCD 多线程-GCD-串行并行 多线程-GCD.png GCD-线程的通讯、延时操作、定时器 GCD-线...

  • iOS 多线程--GCD

    一、GCD基本介绍 1.GCD简介 GCD是Grand Central Dispatch的缩写,GCD是苹果推出的...

  • 自用算法模板(JAVA版)

    一、数论 1)GCD GCD(求最大公约数) QGCD(快速GCD) extGCD(拓展GCD,解决ax + by...

  • GCD介绍

    一、GCD简单介绍 什么是GCD GCD优势 任务和队列 GCD有2个核心概念 GCD的使用就2个步骤 将任务添加...

  • 7.多线程基础(七)GCD加强

    1.GCD串行队列和并发队列 2.GCD延时执行 3.GCD线程组:(的作用) 4.GCD定时器: GCD的实现 ...

网友评论

      本文标题:GCD

      本文链接:https://www.haomeiwen.com/subject/htlrixtx.html