Swift4中使用GCD----主队列

2018-04-03  本文已影响0人  青山不改

1.主队列异步任务

    override func viewDidLoad() {
        super.viewDidLoad()
        //获取主队列
        let main = DispatchQueue.main
        
        for i in 1...10 {
            //依次添加异步任务,先添加的先执行
            print("主线程===\(Thread.current)")
            main.async {
                let j = arc4random_uniform(UInt32(5))//随机一个时间
                sleep(j)//耗时任务
                print("任务线程===\(Thread.current)")
                print("任务\(i)完成,耗时\(j)秒")
            }
            print("任务\(i)开始")
        }
        
    }

主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务1开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务2开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务3开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务4开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务5开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务6开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务7开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务8开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务9开始
主线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务10开始
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务1完成,耗时2秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务2完成,耗时1秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务3完成,耗时0秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务4完成,耗时4秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务5完成,耗时1秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务6完成,耗时1秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务7完成,耗时0秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务8完成,耗时2秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务9完成,耗时0秒
任务线程===<NSThread: 0x600000068840>{number = 1, name = main}
任务10完成,耗时3秒

小结:
1.异步任务都是立即返回的,也就是分配完任务,就接着执行下面的“print("任务(i)开始")”;
2.主队列(串行队列)里的任务是按顺序执行的,不管任务耗时几秒,都是等上一个结束,才会执行下一个;
3.主队列里的异步任务并没有开启新的线程,而是在当前线程完成的异步任务。

2.主队列同步任务

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //获取主队列
        let main = DispatchQueue.main
        
        for i in 1...10 {
            //依次添加异步任务,先添加的先执行
            print("主线程===\(Thread.current)")
            main.sync {
                let j = arc4random_uniform(UInt32(5))//随机一个时间
                sleep(j)//耗时任务
                print("任务线程===\(Thread.current)")
                print("任务\(i)完成,耗时\(j)秒")
            }
            print("任务\(i)开始")
        }

    }

这时候会得到一个错误"Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)"


主队列是个串行队列,viewDidLoad也是运行在主队列的任务,viewDidLoad已经在执行了,但是这里viewDidLoad里边添加了一个同步任务,必须要等这个同步任务结束以后才会执行下面的print("任务(i)开始"),但是,因为串行队列是先进先出的,viewDidLoad还没执行完,不会执行同步任务,所以就造成了同步任务等待viewDidLoad执行完,viewDidLoad又等待同步任务执行完,这就是死锁!

上一篇下一篇

猜你喜欢

热点阅读