iOS 锁

作者: qbb_kbb | 来源:发表于2016-06-12 15:42 被阅读0次

1.Synchronized方式

h文件

@interface testLock : NSObject{

   NSString *mStr;

}

- (void)testSynchronized:(NSString *)str;

@implementation testLock

- (void)testSynchronized:(NSString *)str{

   @synchronized (mStr) {

       NSLog(@"testSynchronized_1,str:%@",str);

       NSLog(@"testSynchronized_2,str:%@",str);

       NSLog(@"testSynchronized_3,str:%@",str);

       NSLog(@"testSynchronized_4,str:%@",str);

       mStr = str;

       }

}

main函数:

testLock *tempLock = [[testLock alloc] init:@"temp"];

[tempLock testSynchronized:@"tempLocktestSynchronized"];

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[tempLock testSynchronized:@"test1testSynchronized"];

});

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[tempLock testSynchronized:@"test2testSynchronized"];

});

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[tempLock testSynchronized:@"test3testSynchronized"];

});

输出结果:

2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_1,str:tempLocktestSynchronized

2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_2,str:tempLocktestSynchronized

2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_3,str:tempLocktestSynchronized

2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_4,str:tempLocktestSynchronized

2016-06-12 15:20:30.870 TestRuntime[5407:398223] testSynchronized_1,str:test1testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398223] testSynchronized_2,str:test1testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398223] testSynchronized_3,str:test1testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398223] testSynchronized_4,str:test1testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_1,str:test2testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_2,str:test2testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_3,str:test2testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_4,str:test2testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_1,str:test3testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_2,str:test3testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_3,str:test3testSynchronized

2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_4,str:test3testSynchronized

如果修改对应m文件的内容为:

- (void)testSynchronized:(NSString *)str{

@synchronized (mStr) {

   mStr = str;

   NSLog(@"testSynchronized_1,str:%@",str);

   NSLog(@"testSynchronized_2,str:%@",str);

   NSLog(@"testSynchronized_3,str:%@",str);

   NSLog(@"testSynchronized_4,str:%@",str);

   }

}

则输出为:

2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_1,str:tempLocktestSynchronized

2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_2,str:tempLocktestSynchronized

2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_3,str:tempLocktestSynchronized

2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_4,str:tempLocktestSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_1,str:test1testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_1,str:test2testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_2,str:test1testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_1,str:test3testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_2,str:test2testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_3,str:test1testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_2,str:test3testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_3,str:test3testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_3,str:test2testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_4,str:test1testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_4,str:test3testSynchronized

2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_4,str:test2testSynchronized

从上面的结果可以看出,在对mStr变量做锁定的时候,对mStr的值的改变的语句位置不同会造成@synchronized内部执行顺序的不一样,从输出看,只要mStr的值已经被修改,则锁就好像被释放了?~

2.NSLock

NSLock * lock = [[NSLock alloc]init];

NSMutableArray * piaos = [NSMutableArray arrayWithArray:@[@"a",@"b",@"c"]];

// 线程1

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[lock lock];

NSLog(@"thread1:%@",piaos);

sleep(3);

[piaos removeObject:@"a"];

[lock unlock];

});

// 线程2

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[piaos removeObject:@"b"];

NSLog(@"thread2:%@",piaos);

});

// 线程3

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[lock lock];

NSLog(@"thread3:%@",piaos);

[lock unlock];

});

输出:

2016-06-12 15:32:54.819 TestRuntime[5515:409045] thread1:(

a,

b,

c

)

2016-06-12 15:32:54.819 TestRuntime[5515:409046] thread2:(

a,

c

)

2016-06-12 15:32:57.819 TestRuntime[5515:409047] thread3:(

c

)

所有加相同锁的内容只能按照 [lock lock]以及[lock unlock]的顺序执行,对没有加锁的代码片段没有影响

3.NSConditionLock

NSConditionLock * lock = [[NSConditionLock alloc]init];

//Thread1

dispatch_async(dispatch_get_global_queue(0, 0), ^{

for (int i = 0; i< 4; i++) {

[lock lock];

NSLog(@"thread1");

[lock unlockWithCondition:i];

sleep(3);

}

});

// Thread2

dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSLog(@"thread2");

});

// Thread3

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[lock lockWhenCondition:3];

NSLog(@"thread3");

[lock unlock];

});

// Thread4

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[lock lockWhenCondition:2];

NSLog(@"thread4");

[lock unlock];

});

输出:

2016-06-12 15:34:45.145 TestRuntime[5531:411155] thread2

2016-06-12 15:34:45.145 TestRuntime[5531:411154] thread1

2016-06-12 15:34:48.146 TestRuntime[5531:411154] thread1

2016-06-12 15:34:51.146 TestRuntime[5531:411154] thread1

2016-06-12 15:34:51.146 TestRuntime[5531:411155] thread4

2016-06-12 15:34:54.148 TestRuntime[5531:411154] thread1

2016-06-12 15:34:54.148 TestRuntime[5531:411156] thread3

满足条件的时候可以lock和unlock,可以随意组合:lock ,lockWhenCondition,unlock,unlockWithCondition

4.NSRecursiveLock

NSRecursiveLock *lock = [[NSRecursiveLock alloc]init];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

static void (^RecursiveMethod)(int);

RecursiveMethod = ^(int value) {

[lock lock];

if (value > 0) {

NSLog(@"value = %d", value);

sleep(1);

RecursiveMethod(value - 1);

}

[lock unlock];

};

RecursiveMethod(5);

});

输出:

2016-06-12 15:36:44.951 TestRuntime[5544:413127] value = 5

2016-06-12 15:36:45.955 TestRuntime[5544:413127] value = 4

2016-06-12 15:36:46.959 TestRuntime[5544:413127] value = 3

2016-06-12 15:36:47.961 TestRuntime[5544:413127] value = 2

2016-06-12 15:36:48.965 TestRuntime[5544:413127] value = 1

如果改用NSLock,发生死锁则会输出:

2016-06-12 15:38:15.877 TestRuntime[5558:414854] value = 52016-06-12 15:38:16.879 TestRuntime[5558:414854] *** -[NSLock lock]: deadlock ('(null)')

2016-06-12 15:38:16.880 TestRuntime[5558:414854] *** Break on _NSLockError() to debug.

NSRecursiveLock会跟踪它被多少次lock。每次成功的lock都必须平衡调用unlock操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得;

5.NSCondition

NSCondition * lock = [[NSCondition alloc]init];

NSMutableArray * piaos = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3"]];

// Thread1

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[lock lock];

NSLog(@"Thread1,lock done");

[lock wait];

NSLog(@"Thread1,wait done");

[lock unlock];

NSLog(@"Thread1,unlock done");

});

// Thread2

dispatch_async(dispatch_get_global_queue(0, 0), ^{

static void (^clearTheObj)(NSMutableArray * array);

clearTheObj = ^(NSMutableArray * array){

NSLog(@"%lu",(unsigned long)array.count);

if ([array count]>0) {

[array removeObjectAtIndex:0];

}else{

[lock signal];

NSLog(@"Thread2,signal done");

return;

}

sleep(1);

clearTheObj(array);

};

[lock lock];

NSLog(@"Thread2,lock done");

clearTheObj(piaos);

NSLog(@"Thread2,clearTheObj done");

[lock unlock];

NSLog(@"Thread2,unlock done");

});

输出:

2016-06-12 15:39:37.653 TestRuntime[5571:415857] Thread1,lock done

2016-06-12 15:39:37.653 TestRuntime[5571:415858] Thread2,lock done

2016-06-12 15:39:37.653 TestRuntime[5571:415858] 3

2016-06-12 15:39:38.657 TestRuntime[5571:415858] 2

2016-06-12 15:39:39.658 TestRuntime[5571:415858] 1

2016-06-12 15:39:40.658 TestRuntime[5571:415858] 0

2016-06-12 15:39:40.658 TestRuntime[5571:415858] Thread2,signal done

2016-06-12 15:39:40.658 TestRuntime[5571:415858] Thread2,clearTheObj done

2016-06-12 15:39:40.658 TestRuntime[5571:415858] Thread2,unlock done

2016-06-12 15:39:40.658 TestRuntime[5571:415857] Thread1,wait done

2016-06-12 15:39:40.658 TestRuntime[5571:415857] Thread1,unlock done

说明,thread1在lock之后,执行了wait,然后会暂停执行,随后thread2获取到线程操作权;

知道thread2 执行了signal,thread1才会停止wait,并且继续往下执行~

相关文章

  • iOS锁系列-目录

    1、 iOS锁系列-NSLock对象锁2、iOS锁系列-NSConditionLock条件锁3、iOS锁系列-NS...

  • 起底多线程同步锁(iOS)

    起底多线程同步锁(iOS) 起底多线程同步锁(iOS)

  • iOS 中常见的几种锁-代码示例

    iOS 中常见的几种锁-代码示例 iOS 中常见的几种锁-代码示例

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • 多线程 (三)iOS中的锁

    ios 多线程--锁

  • iOS 锁

    iOS Lock(锁) 主要介绍常见的锁,以及synchronized、NSLock、递归锁、条件锁的底层分析 借...

  • iOS-锁

    iOS开发中知道的哪些锁? 哪个性能最差? 锁是线程编程同步工具的基础。iOS开发中常用的锁有如下几种: @syn...

  • iOS中的锁笔记

    本文只是我对iOS中锁的学习笔记,没有太深入的研究讲解。先来一张ios中常用锁的性能对照图 锁的分类 自旋锁:在未...

  • iOS和Android代码中实现禁止手机休眠

    (一)iOS平台默认,所有iOS设备在过了设定的休眠时间后,都会自动锁屏。如果你的应用不希望iOS设备自动锁屏,需...

  • iOS的线程安全与锁

    iOS的线程安全与锁

网友评论

      本文标题:iOS 锁

      本文链接:https://www.haomeiwen.com/subject/quiedttx.html