參考文章:
iOS多線程--徹底學會多線程之『GCD』
Swift 3.0 GCD和DispatchQueue 使用解析
這哥們已經寫得很好了,代碼這東西溉苛,不敲一下,總覺得就不是自己的。再者想邦,swift GDC的接口真是改得那個揪心啊~两残!
并行隊列+同步執(zhí)行
不會創(chuàng)建新的線程永毅,而是在當前線程立即執(zhí)行
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}
并行隊列+異步執(zhí)行
會創(chuàng)建新的線程
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)}
串行隊列+異步執(zhí)行
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)}
串行隊列+同步執(zhí)行
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}
主隊列+同步執(zhí)行(這個會死鎖)
主隊列+異步執(zhí)行
雖然是異步的,但由于分配到主隊列中人弓,所以不會創(chuàng)建新的線程沼死。
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}
異步一般情況下會創(chuàng)建新的線程來執(zhí)行任務。
同步隊列需要停止當前正在執(zhí)行的任務立即執(zhí)行任務
串行隊列就是一個接一個的執(zhí)行
并發(fā)隊列就是一起塞進隊列中崔赌,何時執(zhí)行意蛀,創(chuàng)建多少線程執(zhí)行收系統(tǒng)決定
主隊列中的異步任務不會創(chuàng)建新的線程(是不是可以說主隊列只一個主線程)
線程間通信
說得好高大上,其實就是GDC嵌套健芭。
let queue = DispatchQueue.init(label: "com.bear.queue")
queue.async {
print("\(Thread.current)")
DispatchQueue.main.async {
print("\(Thread.current)")
}
}
任務分組
當多個任務進行并發(fā)異步執(zhí)行的時候县钥,任務的執(zhí)行順序是隨機的。此時可以通過barrier將任務進行分組慈迈。分組后組的執(zhí)行順序按代碼順序執(zhí)行若贮。而組內的順序依舊是隨機的。
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(等待任務結束后執(zhí)行)
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有啥區(qū)別呢痒留?-谴麦。-
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()
}