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

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