iOS开发基础35-多线程之NSThread

本文将详细介绍 NSThread 多线程编程的基本使用方法、线程状态的管理、多线程的安全隐患及其解决方案、原子属性和非原子属性的选择,总结这些知识点及其底层逻辑。

一、基本使用

1. 创建和启动线程

在 iOS 中,一个 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. 其他创建线程的方式

创建线程后自动启动线程:

[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

隐式创建并启动线程:

[self performSelectorInBackground:@selector(run) withObject:nil];

优缺点:

优点:

  • 简单快捷,使用方便。

缺点:

  • 无法对线程进行更详细的设置,例如线程优先级、栈大小等。

二、线程状态

1. 线程状态

线程的基本状态包括:新建(New)、就绪(Ready)、运行(Running)、阻塞(Blocked)和死亡(Dead)。

2. 控制线程状态

启动线程:

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

阻塞(暂停)线程:

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

强制停止线程:

+ (void)exit;
// 进入死亡状态

注意:一旦线程停止(死亡)后,无法再次启动该线程。终止线程前,应释放之前分配的资源以避免内存泄漏。

三、安全隐患

1. 多线程的安全隐患

资源共享:

当多个线程访问同一块资源时,可能会引发数据错乱和数据安全问题。例如,多个线程同时访问同一个对象、变量或文件。

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

互斥锁用于防止多线程同时访问同一资源,造成数据不一致。其使用方法如下:

@synchronized(锁对象) { 
    // 需要锁定的代码 
}

注意点:

  • 锁定一段代码只用一把锁,多把锁无效。
  • 锁定的代码范围应尽量小,避免降低执行效率。
  • 如果只有一个地方需要加锁,通常使用 self 作为锁对象。

互斥锁的优缺点:

优点:

  • 能有效防止因多线程抢夺资源造成的数据安全问题。

缺点:

  • 消耗大量的 CPU 资源。

相关专业术语:线程同步

线程同步的意思是多条线程按顺序地执行任务,互斥锁使用了线程同步技术。

3. 自旋锁与互斥锁

共同点

  • 都能够保证同一时间,只有一条线程执行锁定范围的代码。

不同点

  • 互斥锁:如果发现有其他线程正在执行锁定的代码,当前线程会进入 "休眠" 状态,等待其他线程执行完毕,锁被释放后再被 "唤醒"。
  • 自旋锁:如果发现有其他线程正在执行锁定的代码,当前线程将 "一直等待" 锁定代码执行完毕,适合执行非常短的代码。

无论何种锁,都会带来一定的代价。日常开发中,尽量减少使用锁的机会,将耗时操作放在后台执行是多线程的主要目的。

四、原子和非原子属性

1. 属性

在定义属性时,有 nonatomicatomic 两种选择。

  • atomic(原子属性):为 setter 方法加锁,是默认属性。
  • nonatomic(非原子属性):不为 setter 方法加锁。

2. 原子和非原子属性的选择

对比:

  • atomic:多线程安全,但性能较差。
  • nonatomic:性能较好,但不具备线程安全性,适合内存资源有限的移动设备。

iOS 开发建议:

  • 所有属性都声明为 nonatomic
  • 避免多线程争抢同一资源。
  • 将加锁、资源争抢问题交由服务器处理,减轻客户端压力。
posted @ 2015-08-17 20:54  Mr.陳  阅读(329)  评论(0编辑  收藏  举报