iOS多线程开发(三)线程安全
前言
在我们使用多线程技术进行开发的时候,无可避免地就要涉及到系统共享资源的安全隐患,也就是我们这篇博客中想要讨论的问题:线程安全
。
关于
线程安全性
,引用一段百度百科
里面的文字描述:当对一个复杂对象进行某种操作时,从操作开始到操作结束,被操作的对象往往会经历若干非法的中间状态。调用一个函数(假设该函数是正确的)操作某对象常常会使该对象暂时陷入不可用的状态(通常称为不稳定状态),等到操作完全结束,该对象才会重新回到完全可用的状态。如果其他线程企图访问一个处于不可用状态的对象,该对象将不能正确响应从而产生无法预料的结果,如何避免这种情况发生是线程安全性的核心问题。线程同步
具体到实际的开发中,为了确保
线程安全
,我们必须做到线程同步
。所谓线程同步
,就是多个线程在共享系统资源时,协同步调,按预定地先后顺序依次执行,确保数据的正确性
与安全性
。
原子操作
iOS平台下的原子操作函数都以OSAtomic
开头,使用时需要包含头文件<libkern/OSAtomic.h>
。不同线程如果通过原子操作
函数对同一变量进行操作,可以保证一个线程的操作不会影响到其他线程内对此变量的操作,因为这些操作都是原子式
的。原子操作
只能对内置类型
进行操作,所以原子操作
能够同步的线程只能位于同一个进程的地址空间内。关于无锁编程的更多讲解,我推荐朋友们阅读这篇文章——无锁编程以及CAS。
Objective-C语言中,在定义一个属性时可以在@property
的参数中选择atomic
和nonatomic
,既代表原子性
(线程安全)和非原子性
(线程不安全)。然而达到属性的线程安全会消耗大量的系统资源,因而并不适合内存较小的移动设备,所以一般我们都会设置属性的非原子性。而涉及到线程安全的一些数据时,一般要把线程同步地逻辑放在Server端。
使用“锁”
在Objective-C语言中,锁有很多种:NSLock
(一般锁),NSRecursiveLock
(递归锁),NSConditionLock
(条件锁)。关于这些锁的具体使用,大家可以查看官方文档,这里我也给大家推荐一篇博文—– iOS 多线程 锁 互斥 同步。在Objective-C中还有另外一种使用“锁”的机制,就是NSCondition
,这里封装了加锁
和解锁
的操作,想研究的朋友可以直接查阅官方文档。
@synchronized
利用@synchronized互斥锁来锁住代码,直接使用于加锁的对象。1
2
3
4@synchronized(self) {
printf("\n");
//加锁代码
}