17-线程同步方案

17-线程同步方案_第1张图片

17-线程同步方案_第2张图片

线程同步本质:不能让多条线程同时占用一份资源。

一、OSSpinLock(高级锁)

线程阻塞:

  • 外循环:是一直占用着CPU资源。
  • 线程休眠:该线程就不占用CPU资源。
    17-线程同步方案_第3张图片
17-线程同步方案_第4张图片

static修饰的变量不能用调用函数进行初始化,因为函数调用是在运行过程中调用的,static修饰的变量初始化是在编译时就确定的。

不要看到多线程调用同一个方法或访问同一个变量就加锁,要视情况而定。

二、os_unfair_lock (互斥锁、低级锁)

死锁:永远拿不到锁(加锁后没有解锁)。

17-线程同步方案_第5张图片

三、pthread_mutex(低级锁)

17-线程同步方案_第6张图片
  • 递归锁(PTHREAD_MUTEX_RECURSIVE):同一个线程对一把锁可以重复加锁。
    17-线程同步方案_第7张图片
17-线程同步方案_第8张图片
  • pthread_mutex条件
    17-线程同步方案_第9张图片
17-线程同步方案_第10张图片

四、自旋锁、互斥锁的汇编分析:

  • 自旋锁汇编:
    17-线程同步方案_第11张图片
17-线程同步方案_第12张图片
  • 互斥锁汇编:
    17-线程同步方案_第13张图片
17-线程同步方案_第14张图片
17-线程同步方案_第15张图片

五、NSLock、NSRecursiveLock、NSCondition

17-线程同步方案_第16张图片
  • NSLock
#import "NSLockDemo.h"

@interface NSLockDemo()
@property (strong, nonatomic) NSLock *ticketLock;
@property (strong, nonatomic) NSLock *moneyLock;
@end

@implementation NSLockDemo


- (instancetype)init
{
    if (self = [super init]) {
        self.ticketLock = [[NSLock alloc] init];
        self.moneyLock = [[NSLock alloc] init];
    }
    return self;
}

// 死锁:永远拿不到锁
- (void)__saleTicket
{
    [self.ticketLock lock];
    
    [super __saleTicket];
    
    [self.ticketLock unlock];
}
  • NSRecursiveLock
    使用方法和NSLock一样。

  • NSCondition

    17-线程同步方案_第17张图片

#import "NSConditionDemo.h"

@interface NSConditionDemo()
@property (strong, nonatomic) NSCondition *condition;
@property (strong, nonatomic) NSMutableArray *data;
@end

@implementation NSConditionDemo

- (instancetype)init
{
    if (self = [super init]) {
        self.condition = [[NSCondition alloc] init];
        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
{
    [self.condition lock];
    NSLog(@"__remove - begin");
    
    if (self.data.count == 0) {
        // 等待
        [self.condition wait];
    }
    
    [self.data removeLastObject];
    NSLog(@"删除了元素");
    
    [self.condition unlock];
}

// 线程2
// 往数组中添加元素
- (void)__add
{
    [self.condition lock];
    
    sleep(1);
    
    [self.data addObject:@"Test"];
    NSLog(@"添加了元素");
    // 信号
    [self.condition signal];
    
    // 广播
//    [self.condition broadcast];
    [self.condition unlock];
    
}
@end
  • NSConditionLock
    17-线程同步方案_第18张图片
#import "NSConditionLockDemo.h"

@interface NSConditionLockDemo()
@property (strong, nonatomic) NSConditionLock *conditionLock;
@end

@implementation NSConditionLockDemo

- (instancetype)init
{
    if (self = [super init]) {
        //创建锁并设置锁的条件值为1
        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 lockWhenCondition:1];

    //直接加锁,不用根据条件值
     //[self.conditionLock lock];
    NSLog(@"__one");
    sleep(1);
    //解锁,并设置锁的条件值为2。
    [self.conditionLock unlockWithCondition:2];
}

- (void)__two
{
    [self.conditionLock lockWhenCondition:2];
    
    NSLog(@"__two");
    sleep(1);
    
    [self.conditionLock unlockWithCondition:3];
}

- (void)__three
{
    [self.conditionLock lockWhenCondition:3];
    
    NSLog(@"__three");
    
    [self.conditionLock unlock];
}

@end

六、SerialQueue

17-线程同步方案_第19张图片

七、dispatch_semaphore

17-线程同步方案_第20张图片
#import "SemaphoreDemo.h"

@interface SemaphoreDemo()
@property (strong, nonatomic) dispatch_semaphore_t semaphore;
@property (strong, nonatomic) dispatch_semaphore_t ticketSemaphore;
@property (strong, nonatomic) dispatch_semaphore_t moneySemaphore;
@end

@implementation SemaphoreDemo

- (instancetype)init
{
    if (self = [super init]) {
        //设置信号量
        self.semaphore = dispatch_semaphore_create(5);
        self.ticketSemaphore = dispatch_semaphore_create(1);
        self.moneySemaphore = dispatch_semaphore_create(1);
    }
    return self;
}

- (void)__drawMoney
{
    dispatch_semaphore_wait(self.moneySemaphore, DISPATCH_TIME_FOREVER);
    
    [super __drawMoney];
    
    dispatch_semaphore_signal(self.moneySemaphore);
}

- (void)__saveMoney
{
    dispatch_semaphore_wait(self.moneySemaphore, DISPATCH_TIME_FOREVER);
    
    [super __saveMoney];
    
    dispatch_semaphore_signal(self.moneySemaphore);
}

- (void)__saleTicket
{
    dispatch_semaphore_wait(self.ticketSemaphore, DISPATCH_TIME_FOREVER);
    
    [super __saleTicket];
    
    dispatch_semaphore_signal(self.ticketSemaphore);
}

- (void)otherTest
{
    for (int i = 0; i < 20; i++) {
        [[[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil] start];
    }
}

// 线程10、7、6、9、8
- (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);
}

@end

八、@synchronized

17-线程同步方案_第21张图片

九、线程同步方案性能对比

17-线程同步方案_第22张图片

自旋锁、互斥锁的比较

17-线程同步方案_第23张图片

十、atomic和nonatomic

17-线程同步方案_第24张图片
17-线程同步方案_第25张图片

十一、读写安全

17-线程同步方案_第26张图片
  • pthread_rwlock

    17-线程同步方案_第27张图片

  • dispatch_barrier_async

    17-线程同步方案_第28张图片

    ßß

你可能感兴趣的:(17-线程同步方案)