GCD 多線程(同步/異步赫编, 串行/并發(fā))

GCD / OperationQueue

  /**
      總結(jié)GCD:
   Q:實現(xiàn)任務之間有一定的執(zhí)行順序尿褪?
          1. 最簡單的任務嵌套
          1. 異步串形隊列办铡,保證執(zhí)行順序
          2. 柵欄函數(shù)
          3. DispatchGroup組, 組通知group_notify
   Q:并發(fā)隊列同步執(zhí)行耗時任務的問題脐雪?
          會導致主線程卡住付翁,不建議這么寫
   Q: 主隊列執(zhí)行同步任務的問題?
          卡死贮缅,崩潰
   Q: 全局隊列使用柵欄函數(shù)會生效嗎榨咐?
          不會生效。
       
        總結(jié) OperationQueue:
   ?? OperationQueue在對GCD的異步并發(fā)/串行隊列的優(yōu)化谴供。
   寫法簡單:任務的并發(fā)/串行/任務依賴關(guān)系/取消未執(zhí)行任務
   */

主隊列

//MARK: 主隊列
    func 同步主串行隊列() {
        let queue = DispatchQueue.main
        
        queue.sync {
            print("---task1 \(Thread.current)")
        }
        
        queue.sync {
            print("---task2 \(Thread.current)")
        }
        
        queue.sync {
            print("---task3 \(Thread.current)")
        }
        
        queue.sync {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行結(jié)果: 崩潰
         */
    }

全局隊列

    //MARK: 全局隊列
    func 同步全局并發(fā)隊列() {
        let queue = DispatchQueue.global()
        
        queue.sync {
            print("---task1 \(Thread.current)")
        }
        
        queue.sync {
            print("---task2 \(Thread.current)")
        }
        
        queue.sync {
            print("---task3 \(Thread.current)")
        }
        
        queue.sync {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 -> task2 ->   task3 ->  task4
         ---task1 <_NSMainThread: 0x600003978040>{number = 1, name = main}
         ---task2 <_NSMainThread: 0x600003978040>{number = 1, name = main}
         ---task3 <_NSMainThread: 0x600003978040>{number = 1, name = main}
         ---task4 <_NSMainThread: 0x600003978040>{number = 1, name = main}
         */
    }
    
    func 異步全局并發(fā)隊列() {
        let queue = DispatchQueue.global()
        
        queue.async {
            print("---task1 \(Thread.current)")
        }
        
        queue.async {
            print("---task2 \(Thread.current)")
        }
        
        queue.async {
            print("---task3 \(Thread.current)")
        }
        
        queue.async {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 | task2  |   task3  |  task4

         */
    }
    
    func 異步全局并發(fā)隊列加柵欄() {
        let queue = DispatchQueue.global()
        
        queue.async {
            print("---task1 \(Thread.current)")
        }
        //??全局隊列加柵欄函數(shù)不會阻塞隊列任務
        queue.async(group: nil, qos: .default, flags: .barrier) {
            print("---task2 \(Thread.current)")
            sleep(3)
        }
        
        queue.async {
            print("---task3 \(Thread.current)")
        }
        
        queue.async {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 | task2  |   task3  |  task4
         ---task3 <NSThread: 0x600001cdc400>{number = 5, name = (null)}
         ---task4 <NSThread: 0x600001cdc400>{number = 5, name = (null)}
         ---task1 <NSThread: 0x600001cdd200>{number = 9, name = (null)}
         ---task2 <NSThread: 0x600001cdc400>{number = 5, name = (null)}
         */
    }

自定義串形隊列

    //MARK: 自定義串形隊列
    func 同步串行隊列() {
        let queue = DispatchQueue(label: "serial_queue", attributes: .concurrent)
        
        queue.sync {
            print("---task1 \(Thread.current)")
        }
        
        queue.sync {
            print("---task2 \(Thread.current)")
        }
        
        queue.sync {
            print("---task3 \(Thread.current)")
        }
        
        queue.sync {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 -> task2 ->   task3 ->  task4
         ---task1 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
         ---task2 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
         ---task3 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
         ---task4 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
         */
    }
    
    func 異步串行隊列() {
        let queue = DispatchQueue(label: "serial_queue")
        
        queue.async {
            print("---task1 \(Thread.current)")
        }
        
        queue.async {
            print("---task2 \(Thread.current)")
        }
        
        queue.async {
            print("---task3 \(Thread.current)")
        }
        
        queue.async {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 -> task2 ->   task3 ->  task4
         ---task1 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
         ---task2 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
         ---task3 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
         ---task4 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
         */
    }

自定義并發(fā)隊列

    //MARK: 自定義并發(fā)隊列
    func 同步并發(fā)隊列() {
        print("start")
        let queue = DispatchQueue(label: "concurrent_queue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
        for i in 1...10 {
            //?? 會導致主線程卡住块茁,不建議這么寫
            queue.sync {
                sleep(UInt32(Int.random(in: 0...10)))
                print("task \(i) in \(Thread.current)")
            }
        }
        queue.async {
            print("taskxxx  in \(Thread.current)")
        }
        print("end")
        /** 執(zhí)行結(jié)果: 按序執(zhí)行
         start
         task 1 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 2 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 3 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 4 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 5 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 6 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 7 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 8 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 9 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         task 10 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
         end
         taskxxx  in <NSThread: 0x600003dca1c0>{number = 3, name = (null)}
         */
    }
    func 異步并發(fā)隊列() {
        let queue = DispatchQueue(label: "concurrent_queue", attributes: .concurrent)
        
        queue.async {
            print("---task1 \(Thread.current)")
        }
        
        queue.async {
            print("---task2 \(Thread.current)")
        }
        
        queue.async {
            print("---task3 \(Thread.current)")
        }
        
        queue.async {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 | task2 |  task3 |  task4
         ---task4 <NSThread: 0x6000034e8a80>{number = 3, name = (null)}
         ---task2 <NSThread: 0x6000034fc180>{number = 7, name = (null)}
         ---task1 <NSThread: 0x6000034ea9c0>{number = 5, name = (null)}
         ---task3 <NSThread: 0x600003485cc0>{number = 6, name = (null)}
         */
    }
    func 異步并發(fā)隊列中使用柵欄函數(shù)() {
        let queue = DispatchQueue(label: "concurrent_queue", attributes: .concurrent)
        
        queue.async {
            print("---task1 \(Thread.current)")
        }
        //柵欄函數(shù)
        queue.async(group: nil, qos: .default, flags: .barrier) {
            print("---task2 \(Thread.current)")
            sleep(3)
        }
        
        queue.async {
            print("---task3 \(Thread.current)")
        }
        
        queue.async {
            print("---task4 \(Thread.current)")
        }
        /** 執(zhí)行順序: task1 -> task2 -> task3 | task4
         ---task1 <NSThread: 0x600001724c40>{number = 7, name = (null)}
         ---task2 <NSThread: 0x600001724c40>{number = 7, name = (null)}
         ---task4 <NSThread: 0x600001720740>{number = 3, name = (null)}
         ---task3 <NSThread: 0x600001724c40>{number = 7, name = (null)}
         */
    }

隊列組的使用

    
    //MARK: 隊列組的使用
    func 隊列組() {
        
        let group = DispatchGroup()
        
        let queue = DispatchQueue(label: "concurrent_queueu", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
        
        queue.async {
            print("---task1 \(Thread.current)")
            sleep(3)
        }
        //方案1: 加入組 enter/leave
        //進入組
        group.enter()
        queue.async {
            print("---task2 \(Thread.current)")
            //離開組
            group.leave()
        }
        //方案1: 加入組
        queue.async(group: group, execute: DispatchWorkItem(block: {
            print("---task3 \(Thread.current)")
            sleep(3)
        }))

        queue.async {
            sleep(10)
            print("---task4 \(Thread.current)")
            
        }
        
//        group.notify(queue: DispatchQueue.main, work: DispatchWorkItem(block: {
//            print("---group notify \(Thread.current)")
//        }))
        
        group.notify(queue: queue, work: DispatchWorkItem(block: {
            print("---group notify \(Thread.current)")
        }))
        /**執(zhí)行順序: 只能保證 group notify 在 {task2, task3} 的后面
         ---task1 <NSThread: 0x600003efe8c0>{number = 6, name = (null)}
         ---task3 <NSThread: 0x600003efd5c0>{number = 7, name = (null)}
         ---task2 <NSThread: 0x600003e83ec0>{number = 3, name = (null)}
         ---group notify <NSThread: 0x600003efe8c0>{number = 6, name = (null)}
         ---task4 <NSThread: 0x600003ef4900>{number = 4, name = (null)}

         */
        
    }
    
    func 嵌套任務() {
        let queue = DispatchQueue(label: "concurrent_queue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
        
        queue.async {
            sleep(10)
            print("task1 \(Thread.current)")
            queue.async {
                print("task2 \(Thread.current)")
            }
        }
        queue.async {
            print("task3 \(Thread.current)")
        }
        queue.async {
            print("task4 \(Thread.current)")
        }
        /** 執(zhí)行結(jié)果: 只能保證task2在task1的后面
         */
    }

OperationQueue

    
    func 操作隊列任務依賴() {
        let queue = OperationQueue()
        
        let operation1 = BlockOperation {
            sleep(10)
            print("task1 in \(Thread.current)")
        }
        
        let operation2 = BlockOperation {
            print("task2 in \(Thread.current)")
        }
        
        let operation3 = BlockOperation {
            print("task3 in \(Thread.current)")
        }
        
        let operation4 = BlockOperation {
            print("task4 in \(Thread.current)")
        }
        
        //任務之間增加依賴方式簡單
        operation3.addDependency(operation1)
        
        queue.addOperation(operation1)
        queue.addOperation(operation2)
        queue.addOperation(operation3)
        queue.addOperation(operation4)
        
        
    }
    
    func 操作隊列異步串行隊列() {
        let queue = OperationQueue()
        //異步串行隊列
        queue.maxConcurrentOperationCount = 1
        
        let operation1 = BlockOperation {
            sleep(10)
            print("task1 in \(Thread.current)")
        }
        
        let operation2 = BlockOperation {
            print("task2 in \(Thread.current)")
        }
        
        let operation3 = BlockOperation {
            print("task3 in \(Thread.current)")
        }
        
        let operation4 = BlockOperation {
            print("task4 in \(Thread.current)")
        }
        
        queue.addOperation(operation1)
        queue.addOperation(operation2)
        queue.addOperation(operation3)
        queue.addOperation(operation4)
        
    }
    
    func 操作隊列任務柵欄() {
        let queue = OperationQueue()
        //異步串行隊列
        queue.maxConcurrentOperationCount = 1
        //隊列任務取消
        DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: DispatchWorkItem(block: {
            queue.cancelAllOperations()
        }))
        
        let operation1 = BlockOperation {
            sleep(10)
            print("task1 in \(Thread.current)")
        }
        
        let operation2 = BlockOperation {
            print("task2 in \(Thread.current)")
        }
        
        let operation3 = BlockOperation {
            print("task3 in \(Thread.current)")
        }
        
        let operation4 = BlockOperation {
            print("task4 in \(Thread.current)")
        }
        
        queue.addOperation(operation1)
        queue.addBarrierBlock {
            print("task柵欄 in \(Thread.current)")
        }
        queue.addOperation(operation2)
        queue.addOperation(operation3)
        queue.addOperation(operation4)
        
        /**
         task1 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
         task柵欄 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
         task3 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
         task4 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
         task2 in <NSThread: 0x6000022962c0>{number = 4, name = (null)}
         */
    }
    
    func 操作隊列任務的取消() {
        let queue = OperationQueue()
        //隊列任務取消
        DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: DispatchWorkItem(block: {
            queue.cancelAllOperations()
        }))
        
        let operation1 = BlockOperation {
            sleep(10)
            print("task1 in \(Thread.current)")
        }
        
        let operation2 = BlockOperation {
            print("task2 in \(Thread.current)")
        }
        
        let operation3 = BlockOperation {
            print("task3 in \(Thread.current)")
        }
        
        let operation4 = BlockOperation {
            print("task4 in \(Thread.current)")
        }
        
        queue.addOperation(operation1)
        queue.addOperation(operation2)
        queue.addOperation(operation3)
        queue.addOperation(operation4)
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市桂肌,隨后出現(xiàn)的幾起案子数焊,更是在濱河造成了極大的恐慌,老刑警劉巖崎场,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佩耳,死亡現(xiàn)場離奇詭異,居然都是意外死亡谭跨,警方通過查閱死者的電腦和手機干厚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來螃宙,“玉大人蛮瞄,你說我怎么就攤上這事∥酆簦” “怎么了裕坊?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵包竹,是天一觀的道長燕酷。 經(jīng)常有香客問我籍凝,道長,這世上最難降的妖魔是什么苗缩? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任饵蒂,我火速辦了婚禮,結(jié)果婚禮上酱讶,老公的妹妹穿的比我還像新娘退盯。我一直安慰自己,他們只是感情好泻肯,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布渊迁。 她就那樣靜靜地躺著,像睡著了一般灶挟。 火紅的嫁衣襯著肌膚如雪琉朽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天稚铣,我揣著相機與錄音箱叁,去河邊找鬼。 笑死惕医,一個胖子當著我的面吹牛耕漱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抬伺,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼螟够,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了峡钓?” 一聲冷哼從身側(cè)響起齐鲤,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎椒楣,沒想到半個月后给郊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡捧灰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年淆九,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毛俏。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡炭庙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出煌寇,到底是詐尸還是另有隱情焕蹄,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布阀溶,位于F島的核電站腻脏,受9級特大地震影響鸦泳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜永品,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一做鹰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鼎姐,春花似錦钾麸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至献宫,卻和暖如春芋肠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背遵蚜。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工帖池, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吭净。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓睡汹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親寂殉。 傳聞我的和親對象是個殘疾皇子囚巴,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容