5. 鎖

==1.@synchronize==
  • 用于單例創(chuàng)建,使多線程下保證唯一對象
  • 代碼塊可用于數(shù)組中唯一線程讀寫
==2.atomic==
  • 是對象的屬性關(guān)鍵字,負(fù)責(zé)對象的原子性操作,不負(fù)責(zé)對象的使用
  • atomic 系統(tǒng)會在生成的setter/getter方法里添加鎖,但是這個鎖僅僅是保證了setter/getter存取的安全,并不能保證數(shù)據(jù)結(jié)果正確
  • A、B、C等多個線程都要操作同一個對象setter,D線程要getter這個對象的值,那么每個線程都成保證各自數(shù)據(jù)的完整性,但是D線程最后get到的值并不能確定。
==3.OSSpinlock==
自旋鎖

循環(huán)等待訪問,不釋放當(dāng)前資源,類似while(1),負(fù)責(zé)輕量級的+1,-1,如在引用計數(shù)的+1,-1操作

==4.NSRecursiveLock==
遞歸鎖

為了解決NSLock在已加鎖的情況下重復(fù)加鎖,調(diào)用NSRecursiveLock的lock方法,可以使加鎖之后仍然獲取到鎖,并且加鎖。加鎖解鎖成對出現(xiàn)。解決多線程下遞歸方法的加鎖。

==4.NSLock==

線程鎖,為了解決線程同步問題

==5.dispatch_semaphore_t==

信號量,實現(xiàn)對線程同步,資源共享訪問的信號量級鎖

1.GCD信號量簡介
//和GCD的group等用法一致,這個函數(shù)是創(chuàng)建一個dispatch_s`emaphore_類型的信號量
//并且創(chuàng)建的時候需要指定信號量的大小。
dispatch_semaphore_create(long value); // 創(chuàng)建信號量

//發(fā)送信號量。該函數(shù)會對信號量的值進(jìn)行加1操作。
dispatch_semaphore_signal(dispatch_semaphore_t deem); // 發(fā)送信號量

//等待信號量。如果信號量值為0,那么該函數(shù)就會一直等待,也就是不返回(相當(dāng)于阻塞當(dāng)前線程)
//直到該函數(shù)等待的信號量的值大于等于1,該函數(shù)會對信號量的值進(jìn)行減1操作,然后返回。
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等待信號量
2.用信號量機(jī)制使異步線程完成同步操作

兩個任務(wù)雖然是異步的,但仍需要同步執(zhí)行

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_group_t grp = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_async(grp, queue, ^{
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        NSLog(@"task1 begin : %@",[NSThread currentThread]);
        dispatch_async(queue, ^{
            NSLog(@"task1 finish : %@",[NSThread currentThread]);
            dispatch_semaphore_signal(sema);
        });
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        //先等待task1內(nèi)的信號量 直到 task1 finish
    });
    dispatch_group_async(grp, queue, ^{
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        NSLog(@"task2 begin : %@",[NSThread currentThread]);
        dispatch_async(queue, ^{
            NSLog(@"task2 finish : %@",[NSThread currentThread]);
            dispatch_semaphore_signal(sema);
        });
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    });
    dispatch_group_notify(grp, dispatch_get_main_queue(), ^{
        NSLog(@"refresh UI");
    });
}
3 阻塞請求線程
dispatch_async(queue, 0), ^{
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    [網(wǎng)絡(luò)請求:^{
        //請求回調(diào)
        dispatch_semaphore_signal(sema);  
    }];
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
//多個請求順序執(zhí)行
==6.dispatch_barrier_async和dispatch_barrier_sync==

柵欄方法,用GCD方式實現(xiàn)多讀單寫

dispatch_barrier_sync

需要等待柵欄執(zhí)行完才會執(zhí)行柵欄后面的任務(wù)

dispatch_barrier_async

無需等待柵欄執(zhí)行完,會繼續(xù)往下走(保留在隊列里)

 dispatch_async(queue, ^{
        NSLog(@"----1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----2-----%@", [NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        //會等待內(nèi)部執(zhí)行完才往下走
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });
    dispatch_barrier_sync(queue, ^{
        //會等待內(nèi)部執(zhí)行完才往下走
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"----3-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----4-----%@", [NSThread currentThread]);
    });

線程安全的數(shù)組

  • 對元素的獲取增加dispatch_sync
- (id)objectAtIndex:(NSUInteger)index {
   __block id item = nil;
   dispatch_sync(self.readWriteQuene, ^{
       if (index <= self.array.count - 1) {
           item = [self.array objectAtIndex:index];
       }
   });
   return item;
}
- (nullable id)getFirstObject {
   __block id item = nil;
   dispatch_sync(self.readWriteQuene, ^{
       if (self.array.count > 0) {
           item = [self.array objectAtIndex:0];
       }
   });
   return item;
}
- (nullable id)getLastObject {
   __block id item = nil;
   dispatch_sync(self.readWriteQuene, ^{
       NSUInteger size = self.array.count;
       if (size > 0) {
           item = self.array[size - 1];
       }
   });
   return item;
}
  • 對數(shù)組操作增加?xùn)艡诜椒?/li>
//synchronized 效率最低
- (void)addObject:(id)anObject {
   dispatch_barrier_async(self.readWriteQuene, ^{
       [self.array addObject:anObject];
   });
}

- (void)insertObject:(id)anObject atIndex:(NSUInteger)index {
   dispatch_barrier_async(self.readWriteQuene, ^{
       [self.array insertObject:anObject atIndex:index];
   });
}
//還有很多操作數(shù)組的方法如removeLastObject
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容