iOS 锁

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 锁)