zoukankan      html  css  js  c++  java
  • iOS多线程主题

    下面是:2个并发进程、和2个并发线程的示意图:

    下面介绍三种多线程技术(Thread、Cocoa Operation、Grand Central Dispatch):

    1、最轻量级Thread(需要自己管理线程的生命周期和同步,所以不常用):线程同步对数据的加锁会导致一定的系统开销。但偶尔也会有一定的用处,如Thread.current可以获得当前线程,这种使用就很方便。

    //下面是创建Thread的两种方法
    //方法一:使用类方法,创建线程(创建好,就启动了)
    Thread.detachNewThreadSelector(#selector(addOne), toTarget: self, with: nil)
    //方法二:线程实例化,采用便利构造器
    let thread2 = Thread(target: self, selector: #selector(addTwo), object: nil)
    thread2.start()
    

    2、Cocoa Operation(相关类Operation和OperationQueue):这种方法就不需要关心线程管理和数据同步,只需把重点放在多线程分别要执行的任务。

    其中Operation是个抽象类,使用它必须用它的子类,可以自定义,也可以用BlockOperation类。要让Operation子类的对象,执行它的任务(方法),就需要把这个对象,add进入OperationQueue对象的操作队列,依次执行:
    let blockOne = BlockOperation(block: addOne)
    let blockTwo = BlockOperation(block: addTwo)
    let queue = OperationQueue()
    queue.addOperation(blockOne)
    queue.addOperation(blockTwo)

    3、Grand Central Dispatch(GCD):

    GCD会自动合理地利用更多的CPU内核(即根据系统负载来自动增减线程数量,从而减少了上下文切换,而增加计算效率)、自动管理线程的生命周期(如创建线程、调度任务、自动同步,无需加锁、销毁线程等,使用就不用过多关心这些与处理事物无关的代码),所以方便的GCD是我们学习iOS多线程的重点。
    使用GCD就是使用dispatch queue(调度队列)的对象,用来接受任务并执行,而且与以上两种方法不同的是,dispatch queue是可以并发的,也可以FIFO串行。

    GCD有两种队列(串行、并行,一个队列对象就代表一个线程),用于存放任务,任务的执行也有两种同步、异步执行。具体如何执行,理解下图:

     创建队列

    主队列:主线程中的唯一队列,用于刷新UI(因为主线程主队列是唯一的,所以这种操作也是串行的),所以其他的耗时任务要放到其他线程的队列中执行。获得主队列:let mainQueue = DispatchQueue.main

    自定义队列:

    对于并行队列,有4个常用的执行优先级(由高到低):.userInitiated—>.default—>.utility—>.background,一般最后一个就用于执行不太关心、极其费时的后台任务

    • 创建串行队列:let serial = DispatchQueue(label: "serialQueue"),一个串行队列之中,任务是FIFO的,但是可以创建多个串行队列,而串行队列之间是并发的。
    • 创建并行队列(对于并发任务,一般就用系统提供的全局并行队列):let conflict = DispatchQueue(label: "conflictQueue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
    • 全局并行队列:let globalQueue = DispatchQueue.global(qos: .default),qos就是优先级。

    然后就是创建任务了:

    同步任务:在任务执行时,线程的队列会等待执行完成后,才执行下一个任务,但是却可以追加新的任务(虽然没有立即执行:阻塞)

            let globalQueue = DispatchQueue.global(qos: .default)
            globalQueue.sync {
                addOne()
            }

    异步任务:不会阻塞当前线程

            let globalQueue = DispatchQueue.global(qos: .default)
            globalQueue.async {
                self.addOne()
            }
            let mainQueue = DispatchQueue.main
            mainQueue.async {
                self.addTwo()   //主线程先执行
            }
    
  • 相关阅读:
    jvm 致命问题分析
    java 包引入时*会全部加载吗
    JDK压缩指针
    ArrayList && HashMap扩容策略
    数据结构对齐 堆对齐 栈对齐
    TLS Thread Local Storage
    vue2 设置网页title的问题
    error ...项目路径 ode_moduleschromedriver: Command failed.
    Vue打包后出现一些map文件
    'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序
  • 原文地址:https://www.cnblogs.com/quanxi/p/6240284.html
Copyright © 2011-2022 走看看