推荐系统直接学习小码哥iOS底层原理班---MJ老师的课确实不错,强推一波。ios
并行:多个任务并发(同时)执行 串行:一个任务执行完毕后,再执行下一个任务数组
同步:在当前线程中执行任务,不具有开启新线程的能力 异步:在新的线程中执行任务,具有开启新线程的能力安全
会开辟新线程的两种状况bash
其他状况、所有将会置于当前线程/主线程(主队列任务)下执行。多线程
1块资源可能会被多个线程共享,也就是
多个线程可能会访问同一块资源
并发
读写
进行枷锁操做
等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源异步
#import <libkern/OSAtomic.h>
@interface OSSpinLockDemo()
@property (assign, nonatomic) OSSpinLock lock;
@end
@implementation OSSpinLockDemo
- (instancetype)init
{
if (self = [super init]) {
self.lock = OS_SPINLOCK_INIT;
}
return self;
}
- (void)test
{
OSSpinLockLock(&_lock);
//同步操做
OSSpinLockUnlock(&_lock);
}
@end
复制代码
OSSpinLock目前已经再也不安全,可能会出现优先级反转问题async
若是等待锁的线程优先级较高,它会一直占用着CPU资源,优先级低的线程就有可能得不到资源致使没法释放锁。性能
等待os_unfair_lock锁的线程会处于休眠状态,并不是忙等学习
os_unfair_lock用于取代不安全的OSSpinLock ,从iOS10开始才支持
<os/lock.h>
@interface OSUnfairLockDemo()
@property (assign, nonatomic) os_unfair_lock lock;
@end
@implementation OSUnfairLockDemo
- (instancetype)init
{
if (self = [super init]) {
self.lock = OS_UNFAIR_LOCK_INIT;
}
return self;
}
- (void)__saleTicket
{
os_unfair_lock_lock(&_lock);
//耗时操做
os_unfair_lock_unlock(&_lock);
}
@end
复制代码
PTHREAD_MUTEX_DEFAULT或PTHREAD_MUTEX_NORMAL下的 pthread_mutex 会产生互斥效果
NSLock是对mutex普通锁的封装
容许同一个线程对一把锁进行重复加锁
PTHREAD_MUTEX_RECURSIVE 下的 pthread_mutex 会产生递归效果
![]()
NSRecursiveLock也是对mutex递归锁的封装,API跟NSLock基本一致
@synchronized是对mutex递归锁的封装
@synchronized(obj)内部会生成obj对应的递归锁并存在hash表中,而后进行加锁、解锁操做。性能最差
-(void)test {
@synchronized(self) {
NSLog(@"2");
[self tess];
sleep(5);
}
}
复制代码
可让一个线程在加锁途中等待另外一个线程完成某个动做后继续加锁执行
相似消费者在商场等着商家调货,而后继续购买。
在上锁状态下能够暂时将锁放开,休眠并等待某个条件
当其余线程对条件发送信号,唤醒继续加锁并执行
@interface MutexDemo3()
@property (assign, nonatomic) pthread_mutex_t mutex;
@property (assign, nonatomic) pthread_cond_t cond;
@property (strong, nonatomic) NSMutableArray *data;
@end
@implementation MutexDemo3
- (instancetype)init
{
if (self = [super init]) {
// 初始化属性
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
// 初始化锁
pthread_mutex_init(&_mutex, &attr);
// 销毁属性
pthread_mutexattr_destroy(&attr);
// 初始化条件
pthread_cond_init(&_cond, NULL);
self.data = [NSMutableArray array];
}
return self;
}
- (void)otherTest
{
[[[NSThread alloc] initWithTarget:self selector:@selector(__remove) object:nil] start];
[[[NSThread alloc] initWithTarget:self selector:@selector(__add) object:nil] start];
}
// 线程1
// 删除数组中的元素
- (void)__remove
{
pthread_mutex_lock(&_mutex);
NSLog(@"__remove - begin");
if (self.data.count == 0) {
// 等待唤醒
pthread_cond_wait(&_cond, &_mutex);
}
[self.data removeLastObject];
NSLog(@"删除了元素");
pthread_mutex_unlock(&_mutex);
}
// 线程2
// 往数组中添加元素
- (void)__add
{
pthread_mutex_lock(&_mutex);
sleep(1);
[self.data addObject:@"Test"];
NSLog(@"添加了元素");
// 发送唤醒信号
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_mutex);
}
- (void)dealloc
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
}
@end
复制代码
NSCondition是对mutex和cond的封装
NSConditionLock是对NSCondition的进一步封装,能够设置具体的条件值
- (instancetype)init
{
if (self = [super init]) {
self.conditionLock = [[NSConditionLock alloc] initWithCondition:1];
}
return self;
}
- (void)otherTest
{
[[[NSThread alloc] initWithTarget:self selector:@selector(__one) object:nil] start];
[[[NSThread alloc] initWithTarget:self selector:@selector(__two) object:nil] start];
[[[NSThread alloc] initWithTarget:self selector:@selector(__three) object:nil] start];
}
- (void)__one
{
[self.conditionLock lock];
NSLog(@"__one");
sleep(1);
[self.conditionLock unlockWithCondition:2];
}
- (void)__two
{
[self.conditionLock lockWhenCondition:2];
NSLog(@"__two");
sleep(1);
[self.conditionLock unlockWithCondition:3];
}
复制代码
信号量的初始值为1,表明同时只容许1条线程访问资源,保证线程同步
也能够控制线程的最大并发数
- (void)test
{
// 若是信号量的值 > 0,就让信号量的值减1,而后继续往下执行代码
// 若是信号量的值 <= 0,就会休眠等待,直到信号量的值变成>0,就让信号量的值减1,而后继续往下执行代码
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
sleep(2);
NSLog(@"test - %@", [NSThread currentThread]);
// 让信号量的值+1
dispatch_semaphore_signal(self.semaphore);
}
复制代码
atomic用于保证属性setter、getter的原子性操做,至关于在getter和setter内部加了线程同步的锁
能够参考源码objc4的objc-accessors
读写锁
@interface ViewController ()
@property (strong, nonatomic) dispatch_queue_t queue;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// queue.maxConcurrentOperationCount = 5;
// dispatch_semaphore_create(5);
self.queue = dispatch_queue_create("rw_queue", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_async(self.queue, ^{
[self read];
});
dispatch_async(self.queue, ^{
[self read];
});
dispatch_async(self.queue, ^{
[self read];
});
dispatch_barrier_async(self.queue, ^{
[self write];
});
}
}
- (void)read {
sleep(1);
NSLog(@"read");
}
- (void)write
{
sleep(1);
NSLog(@"write");
}
@end
复制代码
@interface ViewController ()
@property (assign, nonatomic) pthread_rwlock_t lock;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化锁
pthread_rwlock_init(&_lock, NULL);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
[self read];
});
dispatch_async(queue, ^{
[self write];
});
}
}
- (void)read {
pthread_rwlock_rdlock(&_lock);
sleep(1);
NSLog(@"%s", __func__);
pthread_rwlock_unlock(&_lock);
}
- (void)write
{
pthread_rwlock_wrlock(&_lock);
sleep(1);
NSLog(@"%s", __func__);
pthread_rwlock_unlock(&_lock);
}
- (void)dealloc
{
pthread_rwlock_destroy(&_lock);
}
@end
复制代码