多執行緒中如何去保證執行緒安全
阿新 • • 發佈:2019-01-22
一、前言
前段時間看了幾個開源專案,發現他們保持執行緒同步的方式各不相同,有@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);
|