码迷,mamicode.com
首页 > 移动开发 > 详细

iOS学习——锁

时间:2017-11-12 00:30:08      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:等于   被锁   产生   control   get   com   写文件   color   过程   

  在多线程学习中,必然会涉及到不同线程对同一资源的调取,面对这种调用不加以控制,就会产生数据混乱的情况。最常见的情况莫过于买票,多个售票员售票肯定是同时操作,这样就会开启多条线程,但是这种售票方式会产生票数不对的情况。

- (void)demo1 {
    //售票员A
    NSThread *threadA = [[NSThread alloc] initWithTarget:self selector:@selector(sellTikets) object:nil];
    threadA.name = @"threadA";
    [threadA start];
    
    //售票员B
    NSThread *threadB = [[NSThread alloc] initWithTarget:self selector:@selector(sellTikets) object:nil];
    threadB.name = @"threadB";
    [threadB start];
    

}

- (void)sellTikets{
        while (YES) {
            if (self.tiketNum > 0) {
                self.tiketNum -- ;
                NSLog(@"还剩%d张票 %@",self.tiketNum,[NSThread currentThread]);
            }else {
                NSLog(@"票卖完了 %@",[NSThread currentThread]);
          break;
            }
      

        }
 

}
技术分享
这里对于第九张票出售了两次,这就是用多线程产生的数据不安全问题,因为在多线程的资源共享中,就得上一把锁来保证不会出现这种问题
- (void)sellTikets{
        while (YES) {
            @synchronized(self) {
                if (self.tiketNum > 0) {
                    self.tiketNum -- ;
                    NSLog(@"还剩%d张票 %@",self.tiketNum,[NSThread currentThread]);
                }else {
                    NSLog(@"票卖完了 %@",[NSThread currentThread]);
                    break;
                }
            }
      

        }
}
  @syn中需要传一个全局变量参数,不一定是self,但是一定不能传一个局部变量,因为这里的参数作为一个锁,要保证在线程执行的整个过程中都能锁住线程,如果是一个局部变量,线程运行一次就被释放掉了,根本毫无意义。
  互斥锁保证了线程在运行中,每次只有一个线程能访问到被锁住的代码块,其他需要访问的线程则在锁外面睡眠等待,当一个线程执行完毕,才有下一个线程的执行。那么,我们就得提到OC中的另外一个概念,原子性 atomic。在变量的声明时,我们大多是情况下都是用nonatomic,用以提高运行效率,那么atomic的作用在哪里呢?一般我们在写文件的时候,会使用这样的代码:
    NSData*data = [@"iosSynChronized" dataUsingEncoding:NSUTF8StringEncoding];
    [data  writeToFile:@"ios.text" atomically:YES];
  为了保证文件写入时候的安全,我们一般会选择使用原子性。这样,当文字在写入的时候并不是直接创建一个本地文件写数据,而是创建一个虚拟文件,当数据写入完成,然后一次性形成要存储的本地文件,就不会出现,写入的时候你删除文件,修改文件造成的数据冲突。类似于一个锁一样,锁住你要操作的东西,只有完成才能结束。同样,给变量声明atomic也就等于给变量赋值创建了一把锁,只有一个线程完成对该变量的操作,下一个线程才能进行:
@property (atomic, strong) NSObject *lock;
@end

@implementation ViewController
@synthesize lock = _lock;//重新getter和setter方法后,xcode就不会自动帮写成员变量
-(void)setLock:(NSObject *)lock {
    @synchronized (self) {
        _lock = lock;
    }
}
- (NSObject *)lock {
    return _lock;


  锁能够保证数据安全,但同样也因此带来了极大的不便,那就是效率问题,它将所有访问操作都变成了单一操作,会浪费大量时间,这也是苹果的UIKIT同样采用线程不安全方式的原因,考虑到了效率问题。

 

 

iOS学习——锁

标签:等于   被锁   产生   control   get   com   写文件   color   过程   

原文地址:http://www.cnblogs.com/zhulilove/p/7809089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!