1. 程式人生 > >多執行緒中如何去保證執行緒安全

多執行緒中如何去保證執行緒安全

一、前言  

前段時間看了幾個開源專案,發現他們保持執行緒同步的方式各不相同,有@synchronized、NSLock、dispatch_semaphore、NSCondition、pthread_mutex、OSSpinLock。後來網上查了一下,發現他們的實現機制各不相同,效能也各不一樣。

不好意思,我們平常使用最多的@synchronized是效能最差的。

二、介紹與使用

2.1、@synchronized  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 NSObject *obj = [[NSObject alloc] init]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @synchronized(obj) { NSLog(@"需要執行緒同步的操作1 開始"); sleep(3); NSLog(@"需要執行緒同步的操作1 結束"); } }); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1); @synchronized(obj) { NSLog(@"需要執行緒同步的操作2"); } });

 @synchronized(obj)指令使用的obj為該鎖的唯一標識,只有當標識相同時,才為滿足互斥,如果執行緒2中的@synchronized(obj)改為   @synchronized(self),剛執行緒2就不會被阻塞,@synchronized指令實現鎖的優點就是我們不需要在程式碼中顯式的建立鎖物件,便可以實現鎖的機制,但作為一種預防措施,@synchronized塊會隱式的新增一個異常處理例程來保護程式碼,該處理例程會在異常丟擲的時候自動的釋放互斥鎖。所以如果不想讓隱式的異常處理例程帶來額外的開銷,你可以考慮使用鎖物件。

上面結果的執行結果為:

2016-06-29 20:48:35.747 SafeMultiThread[35945:580107] 需要執行緒同步的操作1 開始
2016-06-29 20:48:38.748 SafeMultiThread[35945:580107] 需要執行緒同步的操作1 結束
2016-06-29 20:48:38.749 SafeMultiThread[35945:580118] 需要執行緒同步的操作2

2.2、dispatch_semaphore  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 dispatch_semaphore_t signal = dispatch_semaphore_create(1); dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(signal, overTime); NSLog(@"需要執行緒同步的操作1 開始"); sleep(2); NSLog(@"需要執行緒同步的操作1 結束"); dispatch_semaphore_signal(signal); }); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(1); dispatch_semaphore_wait(signal, overTime);