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,并且繼續往下執行~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 我的博客, 各位看官有時間賞光 鎖 我們在使用多線程的時候多個線程可能會訪問同一塊資源,這樣就很容易引發數據錯亂和...
    VIC_LI閱讀 1,539評論 0 36
  • 本文首發在我的個人博客:http://blog.shenyuanluo.com/,喜歡的朋友歡迎訂閱。 最近公司有...
    shenyuanluo閱讀 3,246評論 4 3
  • iOS開發中知道的哪些鎖? 哪個性能最差? 鎖是線程編程同步工具的基礎。iOS開發中常用的鎖有如下幾種: @syn...
    linbj閱讀 111評論 0 1
  • 一、互斥鎖 百度百科:在編程中,引入了對象互斥鎖的概念,來保證共享數據操作的完整性。每個對象都對應于一個可稱為" ...
    MangK閱讀 7,494評論 1 29
  • 本文所講為其中之一:iOS程序進入后臺后十分鐘之內就會被系統kill掉,怎么解決呢?我想要程序進入后臺后仍然運行計...
    husky_duang閱讀 6,624評論 2 4