zoukankan      html  css  js  c++  java
  • iOS开发——多线程篇——NSThread

    一、基本使用
    1、创建和启动线程
    一个NSThread对象就代表一条线程

    创建、启动线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    [thread start];
    // 线程一启动,就会在线程thread中执行self的run方法

    主线程相关用法
    + (NSThread *)mainThread; // 获得主线程
    - (BOOL)isMainThread; // 是否为主线程
    + (BOOL)isMainThread; // 是否为主线程

    2、其他用法
    获得当前线程
    NSThread *current = [NSThread currentThread];

    线程的名字
    - (void)setName:(NSString *)n;
    - (NSString *)name;

    3、其他创建线程方式
    创建线程后自动启动线程(detach会自动分离(开启)一个新的线程, 并且自动调用start)
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

    隐式创建并启动线程(Swift中不能使用, 苹果认为这个方法不安全)
    [self performSelectorInBackground:@selector(run) withObject:nil];

    上述2种创建线程方式的优缺点
    优点:简单快捷
    缺点:无法对线程进行更详细的设置

    二、线程状态
    1、线程状态

    2、控制线程状态
    启动线程
    - (void)start;
    // 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态

    阻塞(暂停)线程
    + (void)sleepUntilDate:(NSDate *)date;
    + (void)sleepForTimeInterval:(NSTimeInterval)ti;
    // 进入阻塞状态

    强制停止线程
    + (void)exit;
    // 进入死亡状态

    注意:一旦线程停止(死亡)了,就不能再次开启任务
    一旦强行终止线程,后续的所有代码都不会被执行
    注意:在终止线程之前,应该注意释放之前分配的对象!


    三、安全隐患
    1、多线程的安全隐患
    资源共享
    1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源
    比如多个线程访问同一个对象、同一个变量、同一个文件

    当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题

    解决方案

    2、安全隐患解决 – 互斥锁

    互斥锁使用格式
    @synchronized(锁对象) { // 需要锁定的代码 }
    注意:锁定1份代码只用1把锁,用多把锁是无效的
    互斥锁的锁定范围,应该尽量小,锁定范围越大,效率越差!
    如果代码中只有一个地方需要加锁,大多都使用 self
    @synchronized(self) { // 需要锁定的代码 }

    互斥锁的优缺点
    优点:能有效防止因多线程抢夺资源造成的数据安全问题
    缺点:需要消耗大量的CPU资源

    互斥锁的使用前提:多条线程抢夺同一块资源

    相关专业术语:线程同步
    线程同步的意思是:多条线程在同一条线上执行(按顺序地执行任务)
    互斥锁,就是使用了线程同步技术

    3、自旋锁 & 互斥锁
    -共同点
    都能够保证同一时间,只有一条线程执行锁定范围的代码

    -不同点
    互斥锁:如果发现有其他线程正在执行锁定的代码,线程会进入"休眠"状态,等待其他线程执行完毕,打开锁之后,线程会被"唤醒"
    自旋锁:如果发现有其他线程正在执行锁定的代码,线程会"一直等待"锁定代码执行完成!
    自旋锁更适合执行非常短的代码!

    - 无论什么锁,都是要付出代价的!
    - 日常开发中,使用锁的机会很少,多线程的目的,就是将耗时的操作放在后台!


    四、原子和非原子属性
    1、属性
    OC在定义属性时有nonatomic和atomic两种选择
    atomic:原子属性,为setter方法加锁(默认就是atomic)
    nonatomic:非原子属性,不会为setter方法加锁

    2、原子和非原子属性的选择
    nonatomic和atomic对比
    atomic:原子属性(线程安全),就是针对多线程设计的,是默认属性
    多个线程写入属性时,保证同一时间只有一个线程能够执行写入操作
    nonatomic:非线程安全,适合内存小的移动设备

    iOS开发的建议
    所有属性都声明为nonatomic
    尽量避免多线程抢夺同一块资源
    尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力

    五、线程间的通信


    1、线程间通信
    什么叫做线程间通信
    在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信

    线程间通信的体现
    1个线程传递数据给另1个线程
    在1个线程中执行完特定任务后,转到另1个线程继续执行任务

    线程间通信常用方法
    参数:
    waitUntilDone是否等待被调用方法执行完成,有可能也会等待调用方法的执行完成!
    YES: 等待被调用线程执行完毕再执行后面的代码
    NO : 不用等待被调用线程执行完毕就可以执行后面的代码

    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

    将来的你会感谢今天如此努力的你! 版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/chglog/p/4737718.html
Copyright © 2011-2022 走看看