加锁是为了防止多条线程同时访问同一块内存,也就是为了线程同步。实现线程同步不仅仅只有加锁的方式,也可以通过
同步串行
来实现。
BaseOperation.h
#import <Foundation/Foundation.h>
@interface BaseOperation : NSObject
///测试
- (void)test;
- (void)otherTest;
///存钱
- (void)saveMoeney;
///取钱
- (void)withdrawMoeney;
@end
@interface SemphoreOperation : BaseOperation
@end
@interface SynchronizedOperation : BaseOperation
@end
@interface NSConditionLockOperation : BaseOperation
@end
///生产者-消费者模式
@interface NSConditionOperation : BaseOperation
@end
@interface NSLockOperation : BaseOperation
@end
@interface os_unfair_lockOperation : BaseOperation
@end
@interface SerialQueueOperation : BaseOperation
@end
///生产者-消费者模式
@interface MutexOperation : BaseOperation
@end
BaseOperation.m
#import "BaseOperation.h"
#pragma mark - BaseOperation
@interface BaseOperation ()
@property (nonatomic, assign) NSInteger money;
@end
@implementation BaseOperation
- (void)test {
self.money = 100;
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
for (NSInteger i = 0; i < 5; i++) {
[self saveMoeney];
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i < 5; i++) {
[self withdrawMoeney];
}
});
}
- (void)otherTest { }
- (void)saveMoeney {
NSInteger oldMoney = self.money;
sleep(.2);
oldMoney += 50;
self.money = oldMoney;
NSLog(@"存钱50,还剩%ld元 - %@", oldMoney, [NSThread currentThread]);
}
- (void)withdrawMoeney {
NSInteger old = self.money;
sleep(.2);
old -= 50;
self.money = old;
NSLog(@"取钱50后: %ld元 -- %@", self.money, [NSThread currentThread]);
}
@end
#pragma mark - NSConditionOperation
@interface NSConditionOperation ()
@property (nonatomic, strong) NSCondition *condition;
@property (strong, nonatomic) NSMutableArray *dataList;
@end
@implementation NSConditionOperation
- (instancetype)init {
if (self = [super init]) {
self.condition = [[NSCondition alloc] init];
self.dataList = [NSMutableArray array];
}
return self;
}
- (void)otherTest {
[[[NSThread alloc] initWithTarget:self selector:@selector(__consume) object:nil] start];
[[[NSThread alloc] initWithTarget:self selector:@selector(__produce) object:nil] start];
}
///消耗
- (void)__consume {
//加锁
[self.condition lock];
NSLog(@"__consume - begin");
if (self.dataList.count == 0) {
//等待: 阻塞当前线程,直到条件发出信号为止
[self.condition wait];
}
[self.dataList removeLastObject];
NSLog(@"%s %@", __func__, [NSThread currentThread]);
//解锁
[self.condition unlock];
}
///生产
- (void)__produce {
[self.condition lock];
sleep(1);
[self.dataList addObject:@"Lynn Zhang"];
NSLog(@"%s %@", __func__, [NSThread currentThread]);
//唤醒等待的线程
[self.condition signal];
sleep(2);
[self.condition unlock];
}
@end
#pragma mark - NSConditionLock
@interface NSConditionLockOperation ()
@property (nonatomic, strong) NSConditionLock *conditionLock;
@end
@implementation NSConditionLockOperation
- (instancetype)init {
if (self = [super init]) {
//初始化一个NSConditionLock对象
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:3];
NSLog(@"%s, %@", __func__, [NSThread currentThread]);
sleep(1);
//解锁后,重置锁的条件
[self.conditionLock unlockWithCondition:2];
}
- (void)__two {
[self.conditionLock lockWhenCondition:1];
NSLog(@"%s, %@", __func__, [NSThread currentThread]);
sleep(1);
[self.conditionLock unlockWithCondition:3];
}
- (void)__three {
//满足条件时加锁
[self.conditionLock lockWhenCondition:2];
NSLog(@"%s, %@", __func__, [NSThread currentThread]);
sleep(1);
[self.conditionLock unlock];
}
@end
#pragma mark - dispatch_semaphore_t
@interface SemphoreOperation ()
@property (nonatomic, strong) dispatch_semaphore_t semaphore_t;
@end
@implementation SemphoreOperation
- (instancetype)init {
if (self = [super init]) {
self.semaphore_t = dispatch_semaphore_create(1);
}
return self;
}
- (void)saveMoeney {
dispatch_semaphore_wait(self.semaphore_t, DISPATCH_TIME_FOREVER);
[super saveMoeney];
dispatch_semaphore_signal(self.semaphore_t);
}
- (void)withdrawMoeney {
dispatch_semaphore_wait(self.semaphore_t, DISPATCH_TIME_FOREVER);
[super withdrawMoeney];
dispatch_semaphore_signal(self.semaphore_t);
}
@end
#pragma mark - synchronized
@implementation SynchronizedOperation
- (void)saveMoeney {
@synchronized (self) {
[super saveMoeney];
}
}
- (void)withdrawMoeney {
@synchronized (self) {
[super withdrawMoeney];
}
}
@end
#pragma mark - NSLockOperation
@interface NSLockOperation ()
@property (nonatomic, strong) NSLock *lock;
@end
@implementation NSLockOperation
- (instancetype)init {
if (self = [super init]) {
self.lock = [[NSLock alloc] init];
}
return self;
}
- (void)saveMoeney {
[self.lock lock];
[super saveMoeney];
[self.lock unlock];
}
- (void)withdrawMoeney {
[self.lock lock];
[super withdrawMoeney];
[self.lock unlock];
}
@end
#pragma mark - os_unfair_lockOperation
#import <os/lock.h>
@interface os_unfair_lockOperation ()
@property (nonatomic, assign) os_unfair_lock lock;
@end
@implementation os_unfair_lockOperation
- (instancetype)init {
if (self = [super init]) {
self.lock = OS_UNFAIR_LOCK_INIT;
}
return self;
}
- (void)saveMoeney {
os_unfair_lock_lock(&_lock);
[super saveMoeney];
os_unfair_lock_unlock(&_lock);
}
- (void)withdrawMoeney {
os_unfair_lock_lock(&_lock);
[super withdrawMoeney];
os_unfair_lock_unlock(&_lock);
}
@end
#pragma mark - SerialQueueOperation
@interface SerialQueueOperation ()
@property (strong, nonatomic) dispatch_queue_t serialQueue;
@end
@implementation SerialQueueOperation
- (instancetype)init {
if (self = [super init]) {
self.serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (void)saveMoeney {
dispatch_sync(self.serialQueue, ^{
[super saveMoeney];
});
}
- (void)withdrawMoeney {
dispatch_sync(self.serialQueue, ^{
[super withdrawMoeney];
});
}
@end
#pragma mark - MutexOperation
#import <pthread.h>
@interface MutexOperation()
@property (assign, nonatomic) pthread_mutex_t mutex;
@property (assign, nonatomic) pthread_cond_t cond;
@property (strong, nonatomic) NSMutableArray *data;
@end
@implementation MutexOperation
- (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(__consume) object:nil] start];
[[[NSThread alloc] initWithTarget:self selector:@selector(__produce) object:nil] start];
}
//消费
- (void)__consume {
pthread_mutex_lock(&_mutex);
NSLog(@"__consume - begin");
if (self.data.count == 0) {
// 等待
pthread_cond_wait(&_cond, &_mutex);
}
[self.data removeLastObject];
NSLog(@"删除了元素");
pthread_mutex_unlock(&_mutex);
}
//生产
- (void)__produce {
pthread_mutex_lock(&_mutex);
sleep(1);
[self.data addObject:@"Test"];
NSLog(@"添加了元素");
// 信号
pthread_cond_signal(&_cond);
// 广播
// pthread_cond_broadcast(&_cond);
pthread_mutex_unlock(&_mutex);
}
- (void)dealloc {
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
}
@end
网友评论