搜索
您的当前位置:首页正文

GCD多线程同步实现锁效果

来源:二三娱乐

多线程同步?这个有什么意义呢。
多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。
先来个概念性的东西,理解下

信号量

可以简单理解成线程同步作用和加锁相似。其实同步和加锁是有区别的。只是线程同步的效果和加锁之后的作用一样。具体下一篇会有解释。不废话了,直奔代码

先模拟用户去买票,一共提供三条通道,买票。

没有进行线程同步
线程没有同步

上述是开启三条线程,然后都是同时去对数据进行减减操作。会发现,数据出现异常。那是因为,多条线程同时访问这个数据时候,该线程只是读取到他访问时候的数据,若此时还有其他线程对该数据进行操作的话。则这个数据就会出现异常。

一:GCD中的信号量实现线程同步
- (void)viewDidLoad {
    [super viewDidLoad];
   
    // 实例类person
    self.person = [[Person alloc] init];
    self.person.num = 100;
    
    
    //dispatch_semaphore_create(1) 创建一个信号量,设置信号量的资源数0表示没有资源,调用dispatch_semaphore_wait会立即等待。
    //dispatch_semaphore_signal  发送一个信号会让信号量+1
    //dispatch_semaphore_wait  等待信号会让信号量 —1
    self.semaphore = dispatch_semaphore_create(1);
    
    //模拟三条不同的网络去抢票
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeActionA) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timeActionB) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeActionC) userInfo:nil repeats:YES];
    
}

- (void)timeActionA{
       // 线程A
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        [self.person personA];
        //发送一个信号,自然会让信号总量加1,
        dispatch_semaphore_signal(self.semaphore); 
    });   
}
- (void)timeActionB{    
    // 线程A
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        [self.person personB];
        dispatch_semaphore_signal(self.semaphore);
    });   
}
- (void)timeActionC{   
    // 线程A
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        [self.person personC];
        dispatch_semaphore_signal(self.semaphore);
    });
}

Person类的实现。

-(void)personA{
    self.num--;
    NSLog(@"A票通道  剩余总票:%ld",(long)self.num);}
-(void)personB{
    self.num--;
    NSLog(@"B票通道  剩余总票:%ld",(long)self.num);
}

-(void)personC{
    self.num--;
    NSLog(@"C票通道  剩余总票:%ld",(long)self.num);   
}
模拟抢票Log
一:GCD分组实现线程同步
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 实例类person
    self.person = [[Person alloc] init];
    self.person.num = 100;
    
    //创建队列组队
    self.group = dispatch_group_create();
    
    
    //模拟三条不同的网络去抢票
    [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(timeActionA) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timeActionB) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(timeActionC) userInfo:nil repeats:YES];

    
}

- (void)timeActionA{
    
    //进入组
    dispatch_group_enter(self.group);
    //线程放进队列组
    dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self.person personA];
        //离开组
        dispatch_group_leave(self.group);
    });
}

- (void)timeActionB{    

    //进入组
    dispatch_group_enter(self.group);
    
    dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        [self.person personB];
        dispatch_group_leave(self.group);
        
    });

}

- (void)timeActionC{
    //进入组
    dispatch_group_enter(self.group);
    
    dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        [self.person personC];
        dispatch_group_leave(self.group); 
    });
}
线程组模拟线程同步
Top