OC中实现锁

 熟悉多线程开发的同学对锁肯定不陌生,但是OC中如何实现锁呢?给大家科普一下。 

 首先构建一个测试用的类,假想它是我们的一个共享资源,method1与method2是互斥的,代码如下:

@implementation TestObj
- (void)method1
{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}
- (void)method2
{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}
@end

1.使用NSLock实现的锁

 

//主线程中
TestObj *obj = [[TestObj alloc] init];
NSLock *lock = [[NSLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [lock lock];
    [obj method1];
    sleep(10);
    [lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    sleep(1);//以保证让线程2的代码后执行
    [lock lock];
    [obj method2];
    [lock unlock];
});

2.使用synchronized关键字构建的锁

当然在Objective-C中你还可以用@synchronized指令快速的实现锁:

//主线程中
TestObj *obj = [[TestObj alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    @synchronized(obj){
        [obj method1];
        sleep(10);
    }
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    sleep(1);
    @synchronized(obj){
        [obj method2];
    }
});

@synchronized指令使用的obj为该锁的唯一标识,只有当标识相同时,才为满足互斥,如果线程2中的@synchronized(obj)改为@synchronized(other),刚线程2就不会被阻塞,@synchronized指令实现锁的优点就是我们不需要在代码中显式的创建锁对象,便可以实现锁的机制,但作为一种预防措施,@synchronized块会隐式的添加一个异常处理例程来保护代码,该处理例程会在异常抛出的时候自动的释放互斥锁。所以如果不想让隐式的异常处理例程带来额外的开销,你可以考虑使用锁对象。

3.使用GCD来实现的”锁”
以上代码构建多线程我们就已经用到了GCD的dispatch_async方法,其实在GCD中也已经提供了一种信号机制,使用它我们也可以来构建一把”锁”(从本质意义上讲,信号量与锁是有区别,具体差异参加信号量与互斥锁之间的区别):

//主线程中
TestObj *obj = [[TestObj alloc] init];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    [obj method1];
    sleep(10);
    dispatch_semaphore_signal(semaphore);
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    sleep(1);
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    [obj method2];
    dispatch_semaphore_signal(semaphore);
});

参考资料:http://www.tanhao.me/pieces/616.html/

时间: 2024-10-12 12:20:09

OC中实现锁的相关文章

深入理解 iOS 开发中的锁

来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大量的实战经验,另一方面这样的文章相当多,比如 iOS中保证线程安全的几种方式与性能对比.iOS 常见知识点(三):Lock.本文也不会详细介绍锁的具体实现原理,这会涉及到太多相关知识,笔者不敢误人子弟. 本文要做的就是简单的分析 iOS 开发中常见的几种锁如何实现,以及优缺点是什么,为什么会有性能上

OC中协议, 类目, 时间, 延展, 属性

必须接受marryprotocol协议, id<marryprotocol>基于类型的限定, 才能给实例变量赋值 @property (nonatomic, assign) id<marryprotocol> husband; 避免Optitonal没有实现的功能 if ([_husband respondsToSelector:@selector(driver)]) { [_husband driver]; } @required//必须实现的协议, 默认协议 - (void)s

OC中并发编程的相关API和面临的挑战

OC中并发编程的相关API和面临的挑战(1) 小引 http://www.objc.io/站点主要以杂志的形式,深入挖掘在OC中的最佳编程实践和高级技术,每个月探讨一个主题,每个主题都会有几篇相关的文章出炉,2013年7月份的主题是并发编程,今天挑选其中的第2篇文章(Concurrent Programming: APIs and Challenges)进行翻译,与大家分享一下主要内容.由于内容比较多,我将分两部分翻译(API和难点)完成,翻译中,如有错误,还请指正. 目录 1.介绍 2.OS

关于OC中直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型

关于OC直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型,我们完全可以把其转换为OC对象来进项打印调试,而不必对结构体中的成员变量进行打印.就好比我们可以使用NSStringFromCGRect(CGRect rect)来直接打印一个结构体,其他打印可以参考以下内容 UIKIT_EXTERN NSString *NSStringFromCGPoint(CGPoint point); UIKIT_EXTERN NSString *NSStringFrom

【学习ios之路:Objective-C】OC中常用的系统排序方法

①.OC中常用排序方法: 1).不可变数组 - (NSArray *)sortedArrayUsingSelector:(SEL)comparator; - (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr; 2)可变数组 - (void)sortUsingSelector:(SEL)comparator; - (void)sortUsingComparator:(NSComparator)cmptr; 3).字典排序 - (NS

Mysql中那些锁机制之InnoDB

我们知道mysql在曾经.存储引擎默认是MyISAM.可是随着对事务和并发的要求越来越高,便引入了InnoDB引擎.它具有支持事务安全等一系列特性. InnoDB锁模式 InnoDB实现了两种类型的行锁. 共享锁(S):同意一个事务去读一行,阻止其它事务获得同样的数据集的排他锁. 排他锁(X):同意获得排他锁的事务更新数据,可是组织其它事务获得同样数据集的共享锁和排他锁. 能够这么理解: 共享锁就是我读的时候,你能够读,可是不能写.排他锁就是我写的时候.你不能读也不能写.事实上就是MyISAM的

Innodb中的锁

虽然比较擅长的是Oracle,但是公司使用的是MySQL数据库,所以不得不对MySQL数据库多研究一下.今天就谈一下MySQL中的锁. 谈锁之前,要明白为什么会有锁这种东西.之所以有锁,大部分情况下是为了实现事务(transaction)之间的隔离,那么事务之间有几种隔离方式,各种隔离方式又是为了达到什么效果呢?先来说一下各种读现象. 脏读:即一个事务A读取了事务B还没有提交过的数据: 不可重复读:即事务A在第一次按照某条SQL语句读取后跟第二次按照相同的SQL语句读取数据库,这段时间内,事务B

关于void*类型的用法(相当于OC中的id类型)

关于void*类型的用法(相当于OC中的id类型) 1.C++语言在对于void* 类型的使用很特别,因为void* 可以间接引用任何其他数据类型的指针,比如int*.float*甚至抽象数据类型的指针,而且可以从void* 强制转换为任何其他数据类型的指针,所以使用起来有时候会比较危险.如果开始将一个void*的指针间接引用一个float*的指针,然后将这个void*指针强制转化为一个int*类型的指针,编译器不会给出错误甚至警告,但是输出的数据却匪夷所思,如果再强制转换会float*则不会出

智能指针 与 oc中的指针

智能指针 与 oc中的指针 智能指针的原理及实现 当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝:另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享. 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count).智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针. 每次创建类的新对象时,初始化指针并将引用计数置为1:当对象作为另一对象的副