OSSpinLock叫作"自旋鎖",等待鎖的線程會處於忙等狀態,一直佔用着cpu資源。因爲可能會出現優先級反轉的問題,是個不安全鎖。在iOS10蘋果已經不推薦使用了安全
若是等待鎖的線程優先級較高,它會一直佔用着CPU資源,優先級低的線程就沒法釋放 使用的時候須要導入#import <libkern/OSAtomic.h>併發
OSSpinLock lock = OS_SPINLOCK_INIT; bool result = OSSpinLockTry(lock);// 嘗試加鎖(若是須要等待就不加鎖,直接返回false,若是不須要等待就加鎖,返回true) OSSpinLockLock(lock); // 加鎖 OSSpinLockUnlock(lock);// 不加鎖
os_unfair_lock用於取代不安全的OSSpinLock,iOS10之後才支持spa
相比較於OSSpinLock的區別,等待os_unfair_lock鎖的線程會處於休眠狀態,並不是忙等線程
使用時,如要導入頭文件#import <os/lock.h>code
os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; bool result = os_unfair_lock_trylock(&lock); // 嘗試加鎖 返回值=是否加鎖成功 os_unfair_lock_lock(&lock); // 加鎖 os_unfair_lock_unlock(&lock); // 解鎖
mutex叫作"互斥鎖",等待鎖的線程會處於休眠狀態blog
須要導入頭文件#import <pthread.h>遞歸
// 初始化鎖的屬性 pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); // 初始化鎖 pthread_mutex_t mutex; pthread_mutex_init(&mutex, &attr); // 嘗試加鎖 bool result = pthread_mutex_trylock(&mutex); // 加鎖 pthread_mutex_lock(&mutex); // 解鎖 pthread_mutex_unlock(&mutex); // 銷燬相關資源 pthread_mutexattr_destroy(&attr); pthread_mutex_destroy(&mutex);
遞歸鎖的話,建立方式與互斥鎖的方式相同,只是在建立pthread_mutexattr_t的以後,設置類型爲PTHREAD_MUTEX_RECURSIVE隊列
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
使用代碼:資源
// 初始化鎖 pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); // 初始化條件 pthread_cond_t condition; pthread_cond_init(&condition, NULL); // 等待條件(進入休眠,放開mutex鎖,被喚醒後,會再次對mutex加鎖) pthread_cond_wait(&condition, &mutex); // 激活一個等待該條件的線程 pthread_cond_signal(&condition); // 激活全部等待該條件的線程 pthread_cond_broadcast(&condition); // 銷燬 pthread_mutex_destroy(&mutex); pthread_cond_destroy(&condition);
NSLock是對mutex普通鎖的封裝同步
NSrecursiveLock是對mutex遞歸鎖的封裝
NSCondition是對mutex和cond的封裝
semaphore叫作"信號量"
信號量的初始值,能夠用來控制線程併發訪問的最大數量
信號量的初始值爲1,表明同時只容許一條線程訪問資源,保證線程同步
使用代碼:
// 信號量的初始值 int value = 1; // 初始化信號量 dispatch_semaphore_t semaphore = dispatch_semaphore_create(value); // 若是信號量的值<=0,當前線程就會進入休眠等待(知道信號量的值>0) // 若是信號量的值>0,就減1,而後往下執行後面的代碼 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // 讓信號量的值加1 dispatch_semaphore_signal(semaphore);
直接使用GCD的串行隊列,也是能夠顯示線程同步的
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ });
@synchronized是對mutex遞歸鎖的封裝
源碼查看:objc4中的objc-sync.mm文件
@synchronized(obj)內部會生成obj對應的遞歸鎖,而後進行加鎖、解鎖操做
使用代碼:
@synchronized (object) { }