多線程

參考文章:
iOS多線程--徹底學會多線程之『GCD』
Swift 3.0 GCD和DispatchQueue 使用解析

這哥們已經寫得很好了,代碼這東西,不敲一下,總覺得就不是自己的。再者,swift GDC的接口真是改得那個揪心啊~!

并行隊列+同步執行

不會創建新的線程,而是在當前線程立即執行

let queue = DispatchQueue.init(label: "com.bear.queue", attributes: .concurrent)

queue.sync {
    print("1-----\(Thread.current)")
}

queue.sync {
    print("2-----\(Thread.current)")
}

queue.sync {
    print("3-----\(Thread.current)")
}

queue.sync {
    print("4-----\(Thread.current)")
}

output:

1-----<NSThread: 0x100a062d0>{number = 1, name = main}
2-----<NSThread: 0x100a062d0>{number = 1, name = main}
3-----<NSThread: 0x100a062d0>{number = 1, name = main}
4-----<NSThread: 0x100a062d0>{number = 1, name = main}

并行隊列+異步執行

會創建新的線程

let queue = DispatchQueue.init(label: "com.bear.queue", attributes: .concurrent)

let sem = DispatchSemaphore.init(value: 0)

queue.async {
    print("1-----\(Thread.current)")
}

queue.async {
    print("2-----\(Thread.current)")
}

queue.async {
    print("3-----\(Thread.current)")
}

queue.async {
    print("4-----\(Thread.current)")
}

output:

3-----<NSThread: 0x100a03570>{number = 3, name = (null)}
2-----<NSThread: 0x100a03650>{number = 4, name = (null)}
1-----<NSThread: 0x100b00160>{number = 2, name = (null)}
4-----<NSThread: 0x100c041d0>{number = 5, name = (null)}

串行隊列+異步執行

let queue = DispatchQueue.init(label: "com.bear.queue")

let sem = DispatchSemaphore.init(value: 0)

queue.async {
    print("1-----\(Thread.current)")
}

queue.async {
    print("2-----\(Thread.current)")
}

queue.async {
    print("3-----\(Thread.current)")
}

queue.async {
    print("4-----\(Thread.current)")
}

output:

1-----<NSThread: 0x100c02ee0>{number = 2, name = (null)}
2-----<NSThread: 0x100c02ee0>{number = 2, name = (null)}
3-----<NSThread: 0x100c02ee0>{number = 2, name = (null)}
4-----<NSThread: 0x100c02ee0>{number = 2, name = (null)}

串行隊列+同步執行

let queue = DispatchQueue.init(label: "com.bear.queue")

queue.sync {
    print("1-----\(Thread.current)")
}

queue.sync {
    print("2-----\(Thread.current)")
}

queue.sync {
    print("3-----\(Thread.current)")
}

queue.sync {
    print("4-----\(Thread.current)")
}

output:

1-----<NSThread: 0x100b06b50>{number = 1, name = main}
2-----<NSThread: 0x100b06b50>{number = 1, name = main}
3-----<NSThread: 0x100b06b50>{number = 1, name = main}
4-----<NSThread: 0x100b06b50>{number = 1, name = main}

主隊列+同步執行(這個會死鎖)

主隊列+異步執行

雖然是異步的,但由于分配到主隊列中,所以不會創建新的線程。

        DispatchQueue.main.async {
            print("1-----\(Thread.current)")
        }
        
        DispatchQueue.main.async {
            print("2-----\(Thread.current)")
        }
        
        DispatchQueue.main.async {
            print("3-----\(Thread.current)")
        }
        
        DispatchQueue.main.async {
            print("4-----\(Thread.current)")
        }

output:

1-----<NSThread: 0x60800006b4c0>{number = 1, name = main}
2-----<NSThread: 0x60800006b4c0>{number = 1, name = main}
3-----<NSThread: 0x60800006b4c0>{number = 1, name = main}
4-----<NSThread: 0x60800006b4c0>{number = 1, name = main}

異步一般情況下會創建新的線程來執行任務。
同步隊列需要停止當前正在執行的任務立即執行任務
串行隊列就是一個接一個的執行
并發隊列就是一起塞進隊列中,何時執行,創建多少線程執行收系統決定
主隊列中的異步任務不會創建新的線程(是不是可以說主隊列只一個主線程)


線程間通信

說得好高大上,其實就是GDC嵌套。

        let queue = DispatchQueue.init(label: "com.bear.queue")
        queue.async {
            print("\(Thread.current)")
            DispatchQueue.main.async {
                print("\(Thread.current)")
            }
        }

任務分組

當多個任務進行并發異步執行的時候,任務的執行順序是隨機的。此時可以通過barrier將任務進行分組。分組后組的執行順序按代碼順序執行。而組內的順序依舊是隨機的。

        let queue = DispatchQueue.init(label: "com.bear.thread", attributes: .concurrent)
        queue.async {
            print("1----\(Thread.current)")
        }
        queue.async {
            print("2----\(Thread.current)")
        }
        queue.async {
            print("3----\(Thread.current)")
        }
        queue.async {
            print("1----\(Thread.current)")
        }
        queue.async {
            print("2----\(Thread.current)")
        }
        queue.async {
            print("3----\(Thread.current)")
        }
        
        queue.async(flags: .barrier) { 
            print("----barrier----")
        }
        
        queue.async {
            print("4----\(Thread.current)")
        }
        queue.async {
            print("5----\(Thread.current)")
        }
        queue.async {
            print("4----\(Thread.current)")
        }
        queue.async {
            print("5----\(Thread.current)")
        }

        queue.async(flags: .barrier) {
            print("----barrier----")
        }

        queue.async {
            print("6----\(Thread.current)")
        }
        queue.async {
            print("7----\(Thread.current)")
        }
        queue.async {
            print("6----\(Thread.current)")
        }
        queue.async {
            print("7----\(Thread.current)")
        }
        

output:

1----<NSThread: 0x60800026a480>{number = 3, name = (null)}
3----<NSThread: 0x600000264ac0>{number = 6, name = (null)}
2----<NSThread: 0x600000264a80>{number = 5, name = (null)}
1----<NSThread: 0x60800026a340>{number = 4, name = (null)}
2----<NSThread: 0x60800026a480>{number = 3, name = (null)}
3----<NSThread: 0x600000264ac0>{number = 6, name = (null)}
----barrier----
4----<NSThread: 0x600000264ac0>{number = 6, name = (null)}
5----<NSThread: 0x60800026a480>{number = 3, name = (null)}
4----<NSThread: 0x600000264ac0>{number = 6, name = (null)}
5----<NSThread: 0x60800026a340>{number = 4, name = (null)}
----barrier----
6----<NSThread: 0x60800026a340>{number = 4, name = (null)}
6----<NSThread: 0x60800026a340>{number = 4, name = (null)}
7----<NSThread: 0x60800026a340>{number = 4, name = (null)}
7----<NSThread: 0x600000264ac0>{number = 6, name = (null)}

延時任務

        let queue = DispatchQueue.init(label: "com.bear.thread", attributes: .concurrent)
        queue.asyncAfter(deadline: DispatchTime.now() + 3) {
            print("hello")
        }

Group(等待任務結束后執行)

        let queue = DispatchQueue.init(label: "com.bear.thread", attributes: .concurrent)
        let group = DispatchGroup.init()
        let sem = DispatchSemaphore.init(value: 0)
        
        queue.async(group: group) { 
            sem.signal()
            print("group 1")
        }
        queue.async(group: group) {
            sem.signal()
            print("group 2")
        }
        queue.async(group: group) {
            sem.signal()
            print("group 3")
        }
        queue.async(group: group) {
            sem.signal()
            print("group 4")
        }
        
        
        group.notify(queue: queue) { 
            sem.wait()
            sem.wait()
            sem.wait()
            sem.wait()
            
            print("end")
        }

output:

group 1
group 4
group 3
group 2
end

DispatchWorkItem

類似dispatch_block_t

        let queue = DispatchQueue.init(label: "com.bear.thread", attributes: .concurrent)
        let dispatchWorkItem : DispatchWorkItem = DispatchWorkItem.init { 
            print("hello")
        }
        dispatchWorkItem.perform()
        dispatchWorkItem.notify(queue: queue) { 
            print("world")
        }

DispatchSource

這個和Timer有啥區別呢?-。-

    func dispatchSource() {
        var count = 0
        let queue = DispatchQueue.init(label: "com.bear.thread", attributes: .concurrent)
        let timer = DispatchSource.makeTimerSource(queue: queue)
        timer.setEventHandler(handler: DispatchWorkItem{
            print("hello world")
            count += 1
            if count >= 5 {
                timer.cancel()
            }
        })
//        timer.scheduleOneshot(deadline: .now())
        timer.scheduleRepeating(deadline: .now() + 3, interval: .seconds(1))
        timer.resume()
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容