什么是线程安全呢?
线程安全:多线程操作共享数据不会出现想不到的结果就是线程安全的,否则,是线程不安全的。
那么最后来总结下
nonatomic肯定不是线程安全的
atomic修饰后,我们为这个对象加了自旋锁, 不会出现多线程同时修改这个值的。至于这个值最终是什么,无法确定,是因为你不知道多线程的调用 顺序,也就无法判断最终的值是什么。 Atomic不能保证对象多线程的安全,它只是能保证你访问的时候给你返回一个完好无损的Value而已。atomic:系统生成的 getter/setter 会保 证 get、set 操作的完整性,不受其他线程影响。getter 还是能得到一个完好无损的对象(可以保证数据的完整性),但这个对象在多线程的情 况下是不能确定的
如果有多个线程同时调用setter的话,不会出现某一个线程执行完setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁 一样,每次只能有一个线程调用对象的setter方法,所以可以保证数据的完整性。
atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的。
仅仅使用atomic并不会使得对象线 程安全,我们还要为对象线程添加互斥锁lock来确保线程的安全。可以参考之前写的《c++原子变量,互斥锁与线程安全》。
死锁产生的四个必要条件:
互斥:一个资源每次只能被一个进程使用(资源独立)。
请求与保持:一个进程因请而阻塞时,对已获得的资源保持不放(不释放锁)。
不剥夺:进程已获得的资源,在未使用之前,不能强行剥夺(抢夺资源)。
循环等待:若干进程之间形成一种头尾相接的循环等待的资源关闭(死循环)。
如何避免死锁?
1.破坏”互斥”条件:系统里取消互斥、若资源一般不被一个进程独占使用,那么死
锁肯定不会发生的,但一般“互斥”条件无法破坏的,因此,在死锁预防里主要破坏其
他三个必要条件,而不去涉及破坏“互斥”条件。2.破坏“请求和保持”条件:
方法1:所有的进程在始运行之前,必须一次性的申请其在整个运行过程各种所需
要的全部资源。
优:简单易实施且。
缺:因为某项资源不满足,进程无法启动,而其他已经满足了的资源也不会得到利
用,严重降低了资源的利用率,造成资源浪费。方法2:该方法对种方法的改进,允许进程只获得运行初期需要的资源,便始运行,
在运行过程中逐步释放掉分配到,已经使用完毕的资源,然后再去请求新的资源。
这样的话资源的利用率会得到提高,也会减少进程的饥饿问题。3.破坏“不剥夺”条件:当一个已经持有了一些资源的进程在提出新的资源请求没有
得到满足时,它必须释放已经保持的所有资源,待以后需要使用的时候再重新申请。
这就意味着进程已占有的资源会被短暂的释放或者说被抢占了。4.破坏“循环等待”条件:可以通过定义资源类型的线性顺序来预防,可以将每个资
源编号,当一个进程占有编号为i的资源时,那么它下一次申请资源只能申请编号。
关联对象是线程安全的吗?
这要涉及到AssociationsManager关联对象管理类
class AssociationsManager {
static OSSpinLock _lock;
static AssociationsHashMap *_map;
// associative references: object pointer -> PtrPtrHashMap.
public:
AssociationsManager() { OSSpinLockLock(&_lock); }
~AssociationsManager() { OSSpinLockUnlock(&_lock); }
AssociationsHashMap &associations() {
if (_map == NULL)
_map = new(::_malloc_internal(sizeof(AssociationsHashMap))) AssociationsHashMap();
return *_map;
}
};
OSSpinLock AssociationsManager::_lock = OS_SPINLOCK_INIT;
AssociationsHashMap *AssociationsManager::_map = NULL;
这里实现了OSSpinLock
和AssociationsHashMap
这两个单例,在构造这个方法的时候,会调用OSSpinLockLock
,而在析构的时候会调用OSSpinLockUnlock
,associations方法可以取得一个AssociationsHashMap
单例,很明显这个管理类通过持有一个自旋锁保证了操作AssociationsHashMap
是线程安全的,所以每次只有一个线程可以对AssociationsHashMap
进行操作。