iOS开发——多线程

Posted 执着的怪味豆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发——多线程相关的知识,希望对你有一定的参考价值。

很多朋友都说ios开发中,最难理解和学习的就是多线程,很多的原理实现都是通过log看到,也比较抽象,本人也是在多线程方面投入过很多脑细胞。。无论这方面的知识掌握和应用起来是否轻松,牢固的基本功、正确的认识理解、再加上充分的实战经验,都能助你将其搞定。这里先介绍一些多线程的知识以及应用,作为讨论,大家共同学习。

一、多线程基本概念

1、线程与进程 

(1)进程:操作系统的每一个应用程序就是一个进程

(2)线程:进程的基本执行单元,一个进程的所有任务都在线程中执行

2、主线程

(1)定义:一个程序运行后,默认会开启1个线程,称为“主线程”或“UI线程”。其他为“子线程”。

(2)作用及注意:线程一般用来 刷新UI界面 ,处理UI事件(比如:点击、滚动、拖拽等事件),避免将耗时的操作放到主线程,以免造成主线程卡顿。

3、多线程原理

(1)是CPU快速的在多个线程之间的切换(自身的随机调度算法)。

(2)同步/异步:

  • 同步:指的就是在当前线程(不一定是主线程)中,从上而下依次执行任务(代码块的阅读顺序),这个就叫做同步。
  • 异步:指不在当前线程中执行了,开辟新的线程执行, 注意:即使在别的线程中执行,也是从上而下依次执行的。

4、iOS多线程实现方案

 

 

5、线程的占用空间:

(1)子线程:512KB。

(2)主线程:512KB。这里官方文档给出的是1M,实际测试为512,可以打印线程的stackSize属性验证。

6、线程的状态和生命周期:

(1)控制线程的状态(以NSThread管理线程为例)

  a、启动线程:- (void)start;

        线程进入就绪状态,当线程执行完毕后自动进入死亡状态。

  b、暂停(阻塞)线程

    + (void)sleepUntilDate:(NSDate *)date;

    + (void)sleepForTimeInterval:(NSTimeInterval)ti;

    线程进入阻塞状态

  c、停止线程

    + (void)exit;

    线程进入死亡状态

(2)状态图

 

 

7、线程的属性(以NSThread管理线程为例,一下是NSTread类中的方法或属性)

 (1)stackSize:占内存大小

 (2)name:名字

 (3)threadPriority:优先级(不推荐使用)

  (4)  qualityOfService:服务质量 

 

二、多线程深入理解

1、线程间资源共享/抢夺

 (1)定义:一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,当多个线程访问同一块资源时,各个线程提取和修改数据不同步,很容易引发数据错乱和数据安全问题。

 (2)互斥锁(线程同步) :解决上面的问题

  • 代码:@synchronized(锁对象) {  需要锁定的代码  }
  • 每一个对象(NSObject)内部都有一个锁(变量),当有线程要进入synchronized到代码块中会先检查对象的锁是打开还是关闭状态,默认锁是打开状态(1),如果是线程执行到代码块内部 会先上锁(0)。如果锁被关闭,再有线程要执行代码块就先等待,直到锁打开才可以进入。
  • 互斥锁的实现流程

      线程执行到synchronized

    i.   检查锁状态 如果是开锁状态转到ii  ,如果上锁转到v 

    ii.   上锁(0)    

    iii.      执行代码块

    iv.    执行完毕 开锁(1)      

    v.       线程等待(就绪状态)

  • 注意:必须使用全局对象来提供“锁”,否则同样锁不住。

2、原子属性

(1)属性中的修饰符

  • nonatomic :非原子属性
  • atomic  : 原子属性,针对多线程设计的,是默认值。保证同一时间只有一个线程能够写入,但是同一个时间多个线程都可以取值。
  • 自旋锁:atomic  本身就有一把锁(自旋锁),保证“单写多读”:单个线程写入,多个线程可以读取。如果发现有其它线程正在锁定代码,线程会用死循环的方式,一直等待锁定的代码执行完成 。自旋锁更适合执行不耗时的代码。
  • iOS开发的建议:
    • 所有属性都声明为nonatomic,移动设备内存小,atomic虽然相对线程安全,但是消耗资源较多。
    • 尽量避免多线程抢夺同一块资源(多个线程访问和修改同一数据)。
    • 尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力。

3、线程安全

1)多个线程同时操作一个全局变量是不安全的,使用自旋锁并不是绝对的安全(因为单写多读)。

(2)线程安全:在多个线程进行读写操作时,仍然能够保证数据的正确 。使用互斥锁可以实现,但是消耗性能。

(3)关于主线程(UI线程):几乎所有UIKit

以上是关于iOS开发——多线程的主要内容,如果未能解决你的问题,请参考以下文章

iOS学习——多线程开发(NSThread)

iOS开发多线程在实际项目中的运用

iOS开发——多线程

iOS开发笔记--iOS图解多线程

iOS多线程开发——GCD的使用与多线程开发浅析

iOS开发多线程篇—多线程简单介绍