swift4.1 GCD的学习

简介

Grand Central Dispatch (GCD) 是Apple开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。
众所周知,GCD, NSOperationQueue, NSThread, pthread是iOS中多线程的几种处理方式,Swift3之前GCD仍是面向过程的写法,所以需要封装一层再使用。Swift3苹果打成Dispatch这个module.你可以通过import进行导入再使用。Swift4,直接使用

特性

GCD可用于多核的并行运算
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

用法

1、串行队列的创建以及嵌套使用
/**串行队列中:1、异步任务按照顺序执行,开启一个线程
    2、同步任务会阻塞主线程
     3、同步嵌套异步:按照顺序执行,等待任务执行完毕才能执行下一个任务
     4、异步嵌套异步任务:顺序执行
 */
func asyncSerial() {
        print("begin \(Thread.current)")
        let queue = DispatchQueue(label: "com.gcd")//默认串行队列
        queue.async(execute: {
            print("1  \(Thread.current)")
        })
        queue.async(execute: {
            print("2  \(Thread.current)")
        })
        queue.async(execute: {
            print("3  \(Thread.current)")
        })
        queue.sync(execute: {
            print("4  \(Thread.current)")
            queue.async {//串行队列中 同步或异步中不能嵌套同步线程 不然会相互等待 死锁 主线程也是一个串行队列
                print("5  \(Thread.current)")
            }
        })
        print("end")
    }

执行结果

begin {number = 1, name = main}
1 {number = 3, name = (null)}
2 {number = 3, name = (null)}
3 {number = 3, name = (null)}
4 {number = 1, name = main}
end
5 {number = 3, name = (null)}

在串行队列中 异步任务会开辟新线程,按照顺序执行,等上一个任务执行完毕,才能执行下一个任务
同步任务会阻塞主线程

2、并行队列的创建以及嵌套使用
 func asyncConcurrent() {
        print("begin \(Thread.current)")
        let queue = DispatchQueue(label: "com.gcd", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.workItem)
        queue.async(execute: {
            
            print("1  \(Thread.current)")
        })
        queue.async(execute: {
            print("2  \(Thread.current)")
            
        })
        queue.sync(execute: {
            print("4  \(Thread.current)")
            queue.async {
                print("5  \(Thread.current)")
            }
        })
        queue.async(execute: {
            print("3  \(Thread.current)")
        })
        
        print("end")
    }

执行结果

begin {number = 1, name = main}
4 {number = 1, name = main}
end
1 {number = 3, name = (null)}
2 {number = 3, name = (null)}
5 {number = 3, name = (null)}
3 {number = 3, name = (null)}

同步执行是在主线程执行按照顺序执行,阻塞主线程,异步执行为开辟新线程

 sleep(2)
 print("4  \(Thread.current)")

执行结果

begin {number = 1, name = main}
1 {number = 3, name = (null)}
2 {number = 3, name = (null)}
4 {number = 1, name = main}
end
5 {number = 4, name = (null)}
3 {number = 4, name = (null)}

3、延迟执行

    func test44(){
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) {
//            print("sss \(NSStringFromClass(self.classForCoder))")
        }
    }

线程安全

当一段代码被多个线程执行,执行后的结果和多个线程依次执行后的结果一致,那么这段代码就是线程安全的。

 func test1(){
        let queue = DispatchQueue.global(qos: DispatchQoS.QoSClass.default)
        queue.async {
            print("1 ")
            sleep(2)
            print("1  end")
        }
        queue.async {
            print("2 ")
            sleep(2)
            print("2  end")
        }
    }

执行结果

1

2
1 end
2 end

想要按照顺序执行 需要用到线程锁 NSLock

func test4(){
        let queue = DispatchQueue.global(qos: DispatchQoS.QoSClass.default)
        let lock = NSLock()
        
        queue.async {
            lock.lock()
            print("1 ")
            sleep(2)
            print("1  end")
            lock.unlock()
        }
        queue.async {
            lock.lock()
            print("2 ")
            sleep(2)
            print("2  end")
            lock.unlock()
        }
    }

执行结果

1
1 end
2
2 end

@synchronized 在swift中已经放弃
信号量的使用

func test5(){
        let semaphore = DispatchSemaphore(value: 1)//创建信号量。为1的时候为线程锁,大于1为最大线程并发数
        let queue = DispatchQueue.global()
        queue.async {
            semaphore.wait()
            print("1 ")
            sleep(2)
            print("1  end")
            semaphore.signal()
        }
        queue.async {
            semaphore.wait()
            print("2 ")
            sleep(2)
            print("2  end")
            semaphore.signal()
        }
        
    }

执行结果:

1
1 end
2
2 end

你可能感兴趣的:(swift4.1 GCD的学习)