iOS底层系列25 -- 线程锁

2021-09-26  本文已影响0人  YanZi_33
//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
}
//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
}

//取款
- (void)drawMoney{
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
}
image.png image.png

OSSpinLock

#import "ViewController.h"
#import <libkern/OSAtomic.h>

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,assign)OSSpinLock lock;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.lock = OS_SPINLOCK_INIT;
    //卖票与存取款 每次执行时,两者只运行其中一个
//    [self ticketsTest];
    [self moneyTest];
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    //加锁
    OSSpinLockLock(&_lock);
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    OSSpinLockUnlock(&_lock);
}

//取款
- (void)drawMoney{
    //加锁
    OSSpinLockLock(&_lock);
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    OSSpinLockUnlock(&_lock);
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    //加锁
    OSSpinLockLock(&_lock);
    
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    OSSpinLockUnlock(&_lock);
}

@end
#import "ViewController.h"
#import <pthread.h>
#import <libkern/OSAtomic.h>

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
//@property(nonatomic,assign)pthread_mutex_t lock;

@property(nonatomic,assign)OSSpinLock lock;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //初始化锁
    self.lock = OS_SPINLOCK_INIT;
 
    [self ticketsTest];
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    //开辟10条子线程,开始卖票
    for (int i = 0; i < 10; i++) {
        [[[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil] start];
    }
}

//卖票
- (void)saleTicket{
    //加锁
    OSSpinLockLock(&_lock);
    
    int oldTicketCount = self.ticketCount;
    sleep(600);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    OSSpinLockUnlock(&_lock);
}

@end
[图片上传中...(Snip20210926_63.png-4e7ac6-1632649343519-0)] Snip20210926_63.png

os_unfair_lock

#import "ViewController.h"
#import <os/lock.h>

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,assign)os_unfair_lock lock;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.lock = OS_UNFAIR_LOCK_INIT;
    //卖票与存取款 每次执行时,两者只运行其中一个
    [self ticketsTest];
//    [self moneyTest];
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    //加锁
    os_unfair_lock_lock(&_lock);
    
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    os_unfair_lock_unlock(&_lock);
}

//取款
- (void)drawMoney{
    //加锁
    os_unfair_lock_lock(&_lock);
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    os_unfair_lock_unlock(&_lock);
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    //加锁
    os_unfair_lock_lock(&_lock);
    
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    os_unfair_lock_unlock(&_lock);
}

@end

pthread_mutex_t

#import "ViewController.h"
#import <pthread.h>

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,assign)pthread_mutex_t lock;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //属性初始化
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
    //锁的初始化
    pthread_mutex_init(&_lock, &attr);
    //属性销毁
    pthread_mutexattr_destroy(&attr);
    
    //卖票与存取款 每次执行时,两者只运行其中一个
//    [self ticketsTest];
    [self moneyTest];
}

//锁的销毁
- (void)dealloc{
    pthread_mutex_destroy(&_lock);
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    //加锁
    pthread_mutex_lock(&_lock);
    
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    pthread_mutex_unlock(&_lock);
}

//取款
- (void)drawMoney{
    //加锁
    pthread_mutex_lock(&_lock);
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    pthread_mutex_unlock(&_lock);
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    //加锁
    pthread_mutex_lock(&_lock);
    
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    pthread_mutex_unlock(&_lock);
}

@end
#import "ViewController.h"
#import <pthread.h>

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,assign)pthread_mutex_t lock;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //属性初始化
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
    //锁的初始化
    pthread_mutex_init(&_lock, &attr);
    //属性销毁
    pthread_mutexattr_destroy(&attr);
    
    [self otherTest1];
}

- (void)dealloc{
    pthread_mutex_destroy(&_lock);
}

- (void)otherTest1{
    //加锁
    pthread_mutex_lock(&_lock);
    NSLog(@"%s",__func__);
    
    [self otherTest2];
    
    //解锁
    pthread_mutex_unlock(&_lock);
}

- (void)otherTest2{
    //加锁
    pthread_mutex_lock(&_lock);
    
    NSLog(@"%s",__func__);
    
    //解锁
    pthread_mutex_unlock(&_lock);
}

@end

#import "ViewController.h"
#import <pthread.h>

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,assign)pthread_mutex_t lock;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //属性初始化
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    //锁的初始化
    pthread_mutex_init(&_lock, &attr);
    //属性销毁
    pthread_mutexattr_destroy(&attr);
    
    //卖票与存取款 每次执行时,两者只运行其中一个
    [self ticketsTest];
}

- (void)dealloc{
    pthread_mutex_destroy(&_lock);
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    for (int i = 0; i < 10; i++) {
        [[[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil] start];
    }
}

//卖票
- (void)saleTicket{
    //加锁
    pthread_mutex_lock(&_lock);
    
    int oldTicketCount = self.ticketCount;
    sleep(600);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    pthread_mutex_unlock(&_lock);
}

@end
image.png
pthread_mutex_lock_init_slow
pthread_mutex_firstfit_lock_wait
psynch_mutexwait
syscall
#import "ViewController.h"
#import <pthread.h>
#import <libkern/OSAtomic.h>

@interface ViewController ()
//线程锁
@property(nonatomic,assign)pthread_mutex_t lock;
//条件
@property(nonatomic,assign)pthread_cond_t cond;
//数据源
@property(nonatomic,strong)NSMutableArray *dataArr;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //属性初始化
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    //锁的初始化
    pthread_mutex_init(&_lock, &attr);
    //属性销毁
    pthread_mutexattr_destroy(&attr);
    //条件初始化
    pthread_cond_init(&_cond, NULL);
    
    self.dataArr = [NSMutableArray array];
    
    [self otherTest];
}

- (void)dealloc{
    pthread_mutex_destroy(&_lock);
    pthread_cond_destroy(&_cond);
}

- (void)otherTest{
    //开辟两条子线程 分别添加与删除 数组元素
    [[[NSThread alloc]initWithTarget:self selector:@selector(removeElement) object:nil] start];
    [[[NSThread alloc]initWithTarget:self selector:@selector(addElement) object:nil] start];
}

//线程1 删除元素
- (void)removeElement{
    //加锁
    pthread_mutex_lock(&_lock);
    
    if (self.dataArr.count == 0) {
        //1.线程1进入休眠
        //2.放开锁 唤醒线程2
        //3.线程1设置自己被唤醒的条件_cond
        //4.线程1被唤醒之后 会再次加锁 然后执行下面的罗
        pthread_cond_wait(&_cond, &_lock);
    }
    
    [self.dataArr removeLastObject];
    NSLog(@"删除了元素");
    
    //解锁
    pthread_mutex_unlock(&_lock);
}

//线程2 添加元素
- (void)addElement{
    //加锁
    pthread_mutex_lock(&_lock);
    
    [self.dataArr addObject:@"test"];
    NSLog(@"添加了元素");
    //唤醒线程1
    pthread_cond_signal(&_cond);
    NSLog(@"-----");
    //解锁
    pthread_mutex_unlock(&_lock);
}
@end

NSLock

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,strong)NSLock *lock;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.lock = [[NSLock alloc]init];
    
    //卖票与存取款 每次执行时,两者只运行其中一个
    [self ticketsTest];
//    [self moneyTest];
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    //加锁
    [self.lock lock];
    
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    [self.lock unlock];
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    //加锁
    [self.lock lock];
    
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    [self.lock unlock];
}

//取款
- (void)drawMoney{
    //加锁
    [self.lock lock];
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    [self.lock unlock];
}
@end

NSRecursiveLock

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,strong)NSRecursiveLock *lock;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.lock = [[NSRecursiveLock alloc]init];
    
    //卖票与存取款 每次执行时,两者只运行其中一个
    [self ticketsTest];
//    [self moneyTest];
}


//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    //加锁
    [self.lock lock];
    
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    
    //解锁
    [self.lock unlock];
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    //加锁
    [self.lock lock];
    
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    [self.lock unlock];
}

//取款
- (void)drawMoney{
    //加锁
    [self.lock lock];
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    //解锁
    [self.lock unlock];
}
@end

NSCondition

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,strong)NSCondition *lock;
//数据源
@property(nonatomic,strong)NSMutableArray *dataArr;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.lock = [[NSCondition alloc]init];
    
    self.dataArr = [[NSMutableArray array]init];
    [self otherTest];
}

- (void)otherTest{
    //开辟两条子线程 分别添加与删除 数组元素
    [[[NSThread alloc]initWithTarget:self selector:@selector(removeElement) object:nil] start];
    [[[NSThread alloc]initWithTarget:self selector:@selector(addElement) object:nil] start];
}

//线程1 删除元素
- (void)removeElement{
    //加锁
    [self.lock lock];

    if (self.dataArr.count == 0) {
        //1.线程1进入休眠
        //2.放开锁 唤醒线程2
        //3.线程1设置自己被唤醒的条件_cond
        //4.线程1被唤醒之后 会再次加锁 然后执行下面的罗
        [self.lock wait];
    }

    [self.dataArr removeLastObject];
    NSLog(@"删除了元素");

    //解锁
    [self.lock unlock];;
}

//线程2 添加元素
- (void)addElement{
    //加锁
    [self.lock lock];

    [self.dataArr addObject:@"test"];
    NSLog(@"添加了元素");
    //唤醒线程1
    [self.lock signal];
    
    //解锁
    [self.lock unlock];
}
@end

NSConditionLock

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//线程锁
@property(nonatomic,strong)NSConditionLock *lock;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.lock = [[NSConditionLock alloc]initWithCondition:1];
}
    
- (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];
}

//线程1
- (void)one{
    //加锁
    [self.lock lockWhenCondition:1];
    
    NSLog(@"one");

    //1.解锁
    //2.将锁内部的condition条件值置为2
    [self.lock unlockWithCondition:2];
}

//线程2
- (void)two{
    //加锁
    [self.lock lockWhenCondition:2];
    
    NSLog(@"two");
    
    //1.解锁
    //2.将锁内部的condition条件值置为3
    [self.lock unlockWithCondition:3];
}

//线程3
- (void)three{
    //加锁
    [self.lock lockWhenCondition:3];
    
    NSLog(@"three");
    
    //解锁
    [self.lock unlock];
}

@end

dispatch_queue

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//串行队列
@property(nonatomic,strong)dispatch_queue_t queue;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //串行队列
    self.queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    //卖票与存取款 每次执行时,两者只运行其中一个
//    [self ticketsTest];
    [self moneyTest];
}

//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    dispatch_sync(self.queue, ^{
        int oldTicketCount = self.ticketCount;
        sleep(0.2);
        oldTicketCount--;
        self.ticketCount = oldTicketCount;
        NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    });
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    dispatch_sync(self.queue, ^{
        int oldMoney = self.money;
        sleep(0.2);
        oldMoney+=50;
        self.money = oldMoney;
        NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    });
}

//取款
- (void)drawMoney{
    dispatch_sync(self.queue, ^{
        int oldMoney = self.money;
        sleep(0.2);
        oldMoney-=30;
        self.money = oldMoney;
        NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    });
}
@end

dispatch_semaphore

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
//信号量
@property(nonatomic,strong)dispatch_semaphore_t semaphore;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.lock = [[NSConditionLock alloc]initWithCondition:1];
    //串行队列
    self.queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    self.semaphore = dispatch_semaphore_create(1);
    
    //卖票与存取款 每次执行时,两者只运行其中一个
//    [self ticketsTest];
    [self moneyTest];
}


//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    //信号量值-1
    //若信号量值>0,继续执行
    //若信号量值<=0,当前子线程阻塞休眠
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
    int oldTicketCount = self.ticketCount;
    sleep(0.2);
    oldTicketCount--;
    self.ticketCount = oldTicketCount;
    NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    //信号量值+1
    dispatch_semaphore_signal(self.semaphore);
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    //信号量值-1
    //若信号量值>0,继续执行
    //若信号量值<=0,当前子线程阻塞休眠
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney+=50;
    self.money = oldMoney;
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    
    //信号量值+1
    dispatch_semaphore_signal(self.semaphore);
}

//取款
- (void)drawMoney{
    //信号量值-1
    //若信号量值>0,继续执行
    //若信号量值<=0,当前子线程阻塞休眠
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
    int oldMoney = self.money;
    sleep(0.2);
    oldMoney-=30;
    self.money = oldMoney;
    NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);

    //信号量值+1
    dispatch_semaphore_signal(self.semaphore);
}
@end

@synchronized

#import "ViewController.h"

@interface ViewController ()
//金额
@property(nonatomic,assign)int money;
//票数
@property(nonatomic,assign)int ticketCount;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //串行队列
    self.queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    self.semaphore = dispatch_semaphore_create(1);
    
    //卖票与存取款 每次执行时,两者只运行其中一个
    [self ticketsTest];
//    [self moneyTest];
}


//卖票测试
- (void)ticketsTest{
    self.ticketCount = 15;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}

//卖票
- (void)saleTicket{
    @synchronized (self) {
        int oldTicketCount = self.ticketCount;
        sleep(0.2);
        oldTicketCount--;
        self.ticketCount = oldTicketCount;
        NSLog(@"还剩%d张票 -- %@",oldTicketCount,[NSThread currentThread]);
    }
}

//存取款测试
- (void)moneyTest{
    self.money = 100;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self saveMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self drawMoney];
        }
    });
}

//存款
- (void)saveMoney{
    @synchronized (self) {
        int oldMoney = self.money;
        sleep(0.2);
        oldMoney+=50;
        self.money = oldMoney;
        NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    }
}

//取款
- (void)drawMoney{
    @synchronized (self) {
        int oldMoney = self.money;
        sleep(0.2);
        oldMoney-=30;
        self.money = oldMoney;
        NSLog(@"还剩%d元 -- %@",oldMoney,[NSThread currentThread]);
    }
}
@end
线程锁的性能比较
上一篇下一篇

猜你喜欢

热点阅读