NSLock线程锁🔐

作者: 请叫我魔法师 | 来源:发表于2017-09-03 19:58 被阅读57次

    顾名思义,就是对一个线程加个锁🔐。具体怎么办,看代码。
    用起来很简单。


    bbbbb.gif

    如果对一个数据在多个线程中都有对它的操作,可能会造成意向不到的结果。
    如下代码,我在两个线程对同一个数组进行删除元素。

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        
        self.dataArr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", nil];
        dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(quene, ^{
            for (int i = 0; i < 8; i++) {
                [self deleteObj];
            }
        });
        
        dispatch_async(quene, ^{
            for (int i = 0; i < 8; i++) {
                [self deleteObj];
            }
        });
    }
    
    - (void)deleteObj {
        
        if (self.dataArr.count > 0) {
            
            NSString *obj = [self.dataArr lastObject];
            NSLog(@"666_SunDePrint_999:删除了%@", obj);
            [self.dataArr removeLastObject];
        }else{
            NSLog(@"666_SunDePrint_999:%@", @"已经删除完了");
        }
    }
    

    结果:


    没加线程锁的结果.png

    很明显看到,第6个元素竟然删除了2遍!!感觉这是不应该发生的,但是它确实发生了。怎么办?当然是加线程锁了。

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        //初始化一个NSLock
        self.lock = [[NSLock alloc] init];
        self.dataArr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", nil];
        dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(quene, ^{
            for (int i = 0; i < 8; i++) {
                [self deleteObj];
            }
        });
        
        dispatch_async(quene, ^{
            for (int i = 0; i < 8; i++) {
                [self deleteObj];
            }
        });
    }
    
    - (void)deleteObj {
        
        [self.lock lock];
        if (self.dataArr.count > 0) {
            NSString *obj = [self.dataArr lastObject];
            NSLog(@"666_SunDePrint_999:删除了%@", obj);
            [self.dataArr removeLastObject];
        }else{
            NSLog(@"666_SunDePrint_999:%@", @"已经删除完了");
        }
        [self.lock unlock];
    }
    

    通过一个NSLock,在对数组操作前先加把锁,不让别的线程访问,操作完后就unlock解锁。

    加完锁🔐的结果.png

    二、@synchronized
    除了NSLock当做线程锁,@synchronized也可以。通过保护一个对象,一般是self,就保护了这个对象的数据。

    - (void)deleteObj {
        
        @synchronized(self){
            
            if (self.dataArr.count > 0) {
                NSString *obj = [self.dataArr lastObject];
                NSLog(@"666_SunDePrint_999:删除了%@", obj);
                [self.dataArr removeLastObject];
                
            }else{
                NSLog(@"666_SunDePrint_999:%@", @"已经删除完了");
            }
        }
    }
    

    效果和NSLock一样。

    相关文章

      网友评论

      本文标题:NSLock线程锁🔐

      本文链接:https://www.haomeiwen.com/subject/dnqrjxtx.html