zoukankan      html  css  js  c++  java
  • iOS学习——锁

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

    - (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同样采用线程不安全方式的原因,考虑到了效率问题。

     
  • 相关阅读:
    负载均衡原理与实践详解 第十六篇 负载均衡网络设计 把负载均衡当作二层交换机还是三层路由器
    谈谈我对技术发展的一点感悟
    解析索引中数据列顺序的选择问题
    构建高性能.NET应用之配置高可用IIS服务器第四篇 IIS常见问题之:工作进程回收机制(上)
    关注分离的艺术(The Art of Separation of Concerns)
    如何修改.net framework
    [WPF Documents 之旅]System.Windows.Documents下的Class Diagram
    [转] 依赖注入&控制反转 oC 容器和Dependency Injection 模式(中文版)
    [WPF疑难]如何禁用窗口上的关闭按钮
    关于书写技术探讨性邮件的一点小小的建议
  • 原文地址:https://www.cnblogs.com/zhulilove/p/7809089.html
Copyright © 2011-2022 走看看