Object-C 多線程中鎖的使用-NSLock


在多線程的編程環境中,鎖的使用必不可少!
於是,今天來總結一下為共享資源加鎖的操作方法。
 
一、使用synchronized方式
 

    //線程1

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        @synchronized(_myLockObj){

            [obj1 method1];

            sleep(30);

        }

        @synchronized(obj1){

 

        

        

        }

    });

    

    //線程2

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        sleep(1);

        @synchronized(_myLockObj){

            [obj1 method2];

        }

    });

    

}

 
這樣,就會起到鎖的作用,線程2會等待線程1執行完成 @synchronized (obj){ }塊后,在執行。從而起到鎖的作用。
 
2.使用NSLock方式
 
先貼一個例子:
 
1. TestObj.h
 

@interface TestObj : NSObject

- (void)method1;

- (void)method2;

@end

 
2. TestObj.m
 

#import "TestObj.h"

 

@implementation TestObj

 

- (void)method1{

    NSLog(@"%@",NSStringFromSelector(_cmd));

    NSLog(@"Current thread = %@", [NSThread currentThread]);

    NSLog(@"Main thread = %@", [NSThread mainThread]);

}

 

- (void)method2{

    NSLog(@"%@",NSStringFromSelector(_cmd));

    NSLog(@"Current thread = %@", [NSThread currentThread]);

    NSLog(@"Main thread = %@", [NSThread mainThread]);

    

}

 

@end

 
3.在需要鎖的視圖控制器中,申明鎖對象。
 

 TestObj *obj = [[TestObj allocinit];

    NSLock *lock = [[NSLock allocinit];

 

4.多線程狀態下,鎖操作

 

 

//線程1

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [lock lock];

        [obj method1];

        sleep(30);

        [lock unlock];

    });

    

    //線程2

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        sleep(5);//以保證讓線程2的代碼后執行

        [lock lock];

        [obj method2];

        [lock unlock];

    });

 
5.總結
 

使用時,基本方法就是:

[lock lock];

[obj yourMethod];

[lock unlock];

 

我們稱[obj yourMethod]關鍵部分

NSLock的執行原理:

某個線程A調用lock方法。這樣,NSLock將被上鎖。可以執行“關鍵部分”,完成后,調用unlock方法。

如果,在線程A 調用unlock方法之前,另一個線程B調用了同一鎖對象的lock方法。那么,線程B只有等待。直到線程A調用了unlock。

 

最后,還是看看API中對NSLock的一些說明

 

 

@protocol NSLocking 

 

 

lock 方法

- (void)lock

獲得鎖

 

unlock 方法

- (void)unlock

釋放鎖

 

@interface NSLock

 

lockBeforeDate: 方法

- (BOOL)lockBeforeDate:(NSDate *)limit

在指定的時間以前得到鎖。YES:在指定時間之前獲得了鎖;NO:在指定時間之前沒有獲得鎖。

該線程將被阻塞,直到獲得了鎖,或者指定時間過期。

 

tryLock 方法

- (BOOL)tryLock

視圖得到一個鎖。YES:成功得到鎖;NO:沒有得到鎖。

 

setName: 方法

- (void)setName:(NSString *)newName

為鎖指定一個Name

 

name 方法

- (NSString *)name

返回鎖指定的Name

 

 

三、使用GCD中dispatch_semaphore_tdispatch_semaphore_wait
 

TestObj *obj = [[TestObj allocinit];

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

    

    //線程1

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        [obj method1];

        sleep(10);

        dispatch_semaphore_signal(semaphore);

    });

    

    //線程2

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        sleep(1);

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        [obj method2];

        dispatch_semaphore_signal(semaphore);

    });

 

------------------------------------------

除此之外,還有NSCondition可以使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM