zoukankan      html  css  js  c++  java
  • 第一篇:线程的安全

    一、资源共享

       我们知道一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,不如多个线程访问同一个对象,同一个变量、同一个文件。当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题。

    例如:我们工厂要生产零件,A生产线和B生产线每个线有1000个零件要生产,但是他们用的是同一个零件箱,那零件箱只能放1000个零件,当他们生产完之后还剩很多零件堆着,这时他们很容易产生矛盾。

    还有就是一个经典的例子:卖票:

    问题代码:

     

    #import "ViewController.h"

     

    @interface ViewController ()

    //剩余的线程

    @property(nonatomic,assign)int Ticket;

    @property(nonatomic,strong)NSThread*thread1;

    @property(nonatomic,strong)NSThread*thread2;

    @property(nonatomic,strong)NSThread*thread3;

    @end

     

    @implementation ViewController

     

    - (void)viewDidLoad

    {

        [super viewDidLoad];

        self.view.backgroundColor=[UIColor whiteColor];

      //有10张票

        self.Ticket=10;

        

     //开启多线程,模拟售票员售票

        self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

        _thread1.name=@"售票员A";

        self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

        _thread2.name=@"售票员B";

        self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

        _thread3.name=@"售票员C";

    }

    -(void)sellTickets

    {

        while (1) {

            //1.先检查票

            int count =self.Ticket;

            if (count>0)

            {

                //暂停一段时间

                [NSThread sleepForTimeInterval:0.1];

                

                

                //2.票数减一

                self.Ticket = count - 1;

                

                //获取当前线程

                NSThread*current=[NSThread currentThread];

                NSLog(@"%@---卖了一张票,还剩%d张票",current,self.Ticket);

            }else

            {

                //退出线程

                [NSThread exit];

                

            }

       

        }

     

    }

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

     

     //开启线程

        [self.thread1 start];

        [self.thread2 start];

        [self.thread3 start];

     

     

    }

    运行结果:

    二、如何解决

    互斥锁使用格式

    @synchronized(锁对象)

    注意:锁定1份代码只用1把锁,用多把锁是无效的

    代码示例:

    互斥锁的优点和缺点

    优点:能有效防止因多线程抢夺资源造成的数据安全问题

    缺点:需要消耗大量的CPU资源

    互斥锁的使用前提:多线程抢夺一块资源

    相关专业术语:线程同步,多条多线程按顺序地执行任务

    互斥锁,就是使用了线程同步技术

    三、原子和非原子属性

    OC在定义属性时有nanatomic和atomic两种选择

    atomic:线程安全,需要消耗大量的资源

    nonatomic:非线程安全,适合内存小的设备

    atomic:原子属性,为setter方法加锁(默认就是atomic)

    nonatomic:非原子属性,不会为setter方法加锁

    atomic加锁原理:

    1 @property (assign, atomic) int age;
    2 
    3 - (void)setAge:(int)age
    4 { 
    5 
    6     @synchronized(self) { 
    7        _age = age;
    8     }
    9 }

    iOS开发的建议

    所有属性都声明为nonatomic

    尽量避免多线程抢夺同一块资源

    尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力



  • 相关阅读:
    Mysql:Group Replication & Replication
    使用winsw包装服务将nginx包装为Windows服务
    Nginx的一些常用配置
    在ASP.NET Core 2.0中使用Facebook进行身份验证
    展现层实现增删改查
    ABP创建应用服务
    ABP领域层定义仓储并实现
    ABP领域层创建实体
    通过模板创建一个ABP项目
    Android UI组件:布局管理器
  • 原文地址:https://www.cnblogs.com/jinchengvs/p/4836431.html
Copyright © 2011-2022 走看看