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 @   路途遥远  阅读(5155)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示