ios专题 -线程互斥与同步

【原创】http://www.cnblogs.com/luoguoqiang1985

今天遇见了这问题,决定要需要讨论下。

线程同步的方法:

  • @synchronized

      官方文档解释:The @synchronized directive is a convenient way to create mutex locks on the fly in Objective-C code.

      个人理解:@synchronized关键字提供了互锁功能。

       示例代码:

     

static NSObject *lockObj = nil;

if (lockObj == nil) {
        lockObj = [[NSObject alloc] init];
    }
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"A thread try lock!");
        @synchronized(lockObj)  {
            NSLog(@"A thread lock, please wait!");
            [NSThread sleepForTimeInterval:10];
            NSLog(@"A thread unlock!");
        }
        
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"B thread try lock!");
        @synchronized(lockObj)  {
            NSLog(@"B thread lock, please wait!");
            [NSThread sleepForTimeInterval:5];
            NSLog(@"B thread unlock!");
        }
        
    });

       执行结果:

     2013-12-28 21:11:02.332 Objc[1341:1b03] A thread try lock!
  2013-12-28 21:11:02.335 Objc[1341:1b03] A thread lock, please wait!
  2013-12-28 21:11:02.332 Objc[1341:3907] B thread try lock!
  2013-12-28 21:11:12.336 Objc[1341:1b03] A thread unlock!
  2013-12-28 21:11:12.336 Objc[1341:3907] B thread lock, please wait!
  2013-12-28 21:11:17.337 Objc[1341:3907] B thread unlock!

     实验结果已经证明同步效果不错!

  •   NSLock

     官方解释:An NSLock object is used to coordinate the operation of multiple threads of execution within the same application. An NSLock object can be used to mediate access to an application’s global data or to protect a critical section of code, allowing it to run atomically.

     个人理解:在一个应用里面协调线程间的执行。

  示例代码:

      昨晚键盘突然坏了,郁闷啊,早上赶紧入货。继续写博了。

     

static NSLock *lockMain = nil;

if (lockMain == nil) {
        lockMain = [[NSLock alloc] init];
    }
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [lockMain lock];
        NSLog(@"A thread begin +!");
        [NSThread sleepForTimeInterval:10];
        NSLog(@"A thread + done and unlock!");
        [lockMain unlock];
        [lockMain lock];
        NSLog(@"A thread begin -!");
        [NSThread sleepForTimeInterval:10];
        NSLog(@"A thread - done and unlock!");
        [lockMain unlock];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [lockMain lock];
        NSLog(@"B thread begin *!");
        [NSThread sleepForTimeInterval:10];
        NSLog(@"B thread * done and unlock!");
        [lockMain unlock];
        [lockMain lock];
        NSLog(@"B thread begin /!");
        [NSThread sleepForTimeInterval:10];
        NSLog(@"B thread / done and unlock!");
        [lockMain unlock];
    });

  执行结果:

2013-12-29 14:37:44.808 Objc[1219:1303] A thread begin +!
2013-12-29 14:37:54.811 Objc[1219:1303] A thread + done and unlock!
2013-12-29 14:37:54.812 Objc[1219:1d03] B thread begin *!
2013-12-29 14:38:04.813 Objc[1219:1d03] B thread * done and unlock!
2013-12-29 14:38:04.813 Objc[1219:1303] A thread begin -!
2013-12-29 14:38:14.815 Objc[1219:1303] A thread - done and unlock!
2013-12-29 14:38:14.816 Objc[1219:1d03] B thread begin /!
2013-12-29 14:38:24.817 Objc[1219:1d03] B thread / done and unlock!

  • NSConditionLock

     官方解释:

  The NSConditionLock class defines objects whose locks can be associated with specific, user-defined conditions. Using an NSConditionLock object, you can ensure that a thread can acquire a lock only if a certain condition is met. Once it has acquired the lock and executed the critical section of code, the thread can relinquish the lock and set the associated condition to something new. The conditions themselves are arbitrary: you define them as needed for your application.

     个人理解:

     根据条件加锁与解锁。

     示例代码:

 

static NSConditionLock *cdtLock = nil;
#define A_THREAD  1
#define B_THREAD  2
#define C_THREAD  3

__block NSInteger a = B_THREAD;
    if (cdtLock == nil) {
        cdtLock = [[NSConditionLock alloc] initWithCondition:a];
    }
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"A thread run!");
        BOOL canLock = [cdtLock tryLockWhenCondition:A_THREAD];
        if (!canLock) {
            NSLog(@"A Thread Lock fail,exit!");
            return ;
        }
        NSLog(@"A thread begin lock!");
        [NSThread sleepForTimeInterval:8];
        NSLog(@"A thread unlock!");
        [cdtLock unlock];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"B thread run!");
        BOOL canLock = [cdtLock tryLockWhenCondition:B_THREAD];
        if (!canLock) {
            NSLog(@"B Thread Lock fail,exit!");
            return ;
        }
        NSLog(@"B thread begin lock!");
        [NSThread sleepForTimeInterval:8];
        NSLog(@"B thread unlock!");
        [cdtLock unlock];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"C thread run!");
        BOOL canLock = [cdtLock tryLockWhenCondition:C_THREAD];
        if (!canLock) {
            NSLog(@"C Thread Lock fail,exit!");
            return ;
        }
        NSLog(@"C thread begin lock!");
        [NSThread sleepForTimeInterval:8];
        NSLog(@"C thread unlock!");
        [cdtLock unlock];
    });

 

     执行结果:

     2013-12-29 20:46:27.426 Objc[6282:1303] A thread run!
   2013-12-29 20:46:27.466 Objc[6282:1303] A Thread Lock fail,exit!
  2013-12-29 20:46:27.426 Objc[6282:1e03] C thread run!
  2013-12-29 20:46:27.468 Objc[6282:1e03] C Thread Lock fail,exit!
  2013-12-29 20:46:27.426 Objc[6282:1c03] B thread run!
  2013-12-29 20:46:27.481 Objc[6282:1c03] B thread begin lock!

  • NSRecursiveLock 递归锁

  官方文档:

NSRecursiveLock defines a lock that may be acquired multiple times by the same thread without causing a deadlock, a situation where a thread is permanently blocked waiting for itself to relinquish a lock. While the locking thread has one or more locks, all other threads are prevented from accessing the code protected by the lock.

      个人理解:

同一个线程可以多次请求加锁,但不会引起死锁。

      示例代码:

static NSRecursiveLock *lock;

 if (lock == nil) {
        lock = [[NSRecursiveLock alloc] init];
    }
    void (^__block DoLog)(int) = ^(int value){
        [lock lock];
        if (value > 0) {
            DoLog(value-1);
        }
        NSLog(@"value is %d", value);
        [lock unlock];
    };
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"test begin");
        DoLog(5);
        NSLog(@"test end");
    });

 

      执行结果:

2013-12-29 21:15:31.567 Objc[6741:1303] test begin
2013-12-29 21:15:31.570 Objc[6741:1303] value is 0
2013-12-29 21:15:31.571 Objc[6741:1303] value is 1
2013-12-29 21:15:31.574 Objc[6741:1303] value is 2
2013-12-29 21:15:31.575 Objc[6741:1303] value is 3
2013-12-29 21:15:31.576 Objc[6741:1303] value is 4
2013-12-29 21:15:31.577 Objc[6741:1303] value is 5
2013-12-29 21:15:31.578 Objc[6741:1303] test end

block竟然也可以递归调用,神奇!

 

posted @ 2013-12-29 21:22  路途遥远  阅读(5151)  评论(0编辑  收藏  举报