Swift- 多线程编程GCD

作者: lxl125z | 来源:发表于2017-03-07 17:31 被阅读1540次

    参考文章:
    1、Swift 3使用GCD和DispatchQueues

    2、线程死锁

    基本概念:

    串行队列:只有一个线程,加入到队列中的操作按添加顺序依次执行。并且还要保证在执行某个任务时,在它前面进入队列的所有任务肯定执行完了。对于每一个不同的串行队列,系统会为这个队列建立唯一的线程来执行代码。

    并发队列:这个队列中的任务也是按照先来后到的顺序开始执行,注意是开始,但是它们的执行结束时间是不确定的,取决于每个任务的耗时。对于n个并发队列,GCD不会创建对应的n个线程而是进行适当的优化

    同步执行:会阻塞当前线程 sync默认会在当前线程执行(系统优化)

    异步执行:异步添加任务

    1、主队列和全局队列

    全局队列(可以设置服务等级(Qos class))

    DispatchQueue.global().async {
      //主队列
      DispatchQueue.main.async {
       
      } 
    }
    

    ps:苹果为了优化性能, sync会尽可能在当前线程来运行

    ps:主线程|当前线程

    print(Thread.main,Thread.current,Thread.isMainThread)
    
    

    2、队列的优先级

    .userInteractive
    .userInitiated
    .default
    .utility
    .background
    .unspecified
    
    

    3、并发队列(Concurrent Queues)

    1、队列默认就是串行执行的(serial)

    //创建并行队列
    let anotherQueue = DispatchQueue(label:"com.appcoda.anotherQueue",qos:.utility,attributes: .concurrent)
    
    

    2、通过定义为initiallyInactive 队列任务不会自动开始执行,需要开发者主动去触发

    let anotherQueue2 = DispatchQueue(label:"com.appcoda.anotherQueue2", 
    qos: .utility,attributes[.concurrent,.initiallyInactive]) 
     //手动触发
     if let queue = inactiveQueue {
                queue.activate()
             }
             
    PS:         
    //Suspend可以挂起一个线程,就是把这个线程暂停了,它占着资源,但不运行,
    //用Resume是继续挂起的线程,让这个线程继续执行下去 
      anotherQueue2.resume()
      anotherQueue2.suspend(        
      
    

    4、延迟执行

    let delay = DispatchTime.now() + .seconds(60)
    DispatchQueue.main. asyncAfter(when: delay) {
     // Do something
    }
    
    

    OC的实现

    let dispatch_time = dispatch_time(DISPATCH_TIME_NOW, Int64(60 * NSEC_PER_SEC))
    /*
    是当前事前, 然后加上 .seconds(60) 代表 60秒。 
    再使用 DispatchQueue.main.after 
    让这个操作在 60 秒后执行
    */
    DispatchTime.now() 
    
    
    

    5、DispatchWorkItem对象

    let workItem = DispatchWorkItem {
        //代码块
      }
    let queue = Dispatchqueue.global()
    //默认在主队列执行(下面是全局队列执行)
    queue.async {
        workItem.perform()
    }
    
    //执行完成后通知
    workItem.notify(queue: Dispatchqueue.main) {
           
        }
    
    

    6、DispatchGroup

    队列组

    //创建 DispatchGroup
    let group =  DispatchGroup()
         //添加队列
            group.enter()
            let queue = DispatchQueue.global()
            queue.async {
                for _ in 0...100{
                    print("全局队列")
                }
              //出队列
            group.leave()
            }
            //如果需要上个队列完成后再执行可以用wait
            //group.wait()
            group.enter()
            let queue2 = DispatchQueue(label: "com.pingan.test", attributes: .concurrent)
            queue2.sync {
                
                for i in 0...10{
                    print("",i)
                }
                group.leave()
            }
            //全部执行完毕后通知
            group.notify(queue: DispatchQueue.main) {
                print("队列执行完毕")
            }
    
    

    错误分析

    1、主线程调用 DispatchQueue.main.sync 同步队列,出现线程阻塞。

    viewDidAppear方法的代码相当于mainQueue的一个任务(假设任务A), 现在它里面加了个sync的{假设任务B}, 意味着任务B只有等任务A完成才能开始, 但是要完成任务A的话就必须先完成任务B,这样相互等待出现线程阻塞。

    相关文章

      网友评论

        本文标题:Swift- 多线程编程GCD

        本文链接:https://www.haomeiwen.com/subject/wpomgttx.html