博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发多线程篇—线程安全
阅读量:6720 次
发布时间:2019-06-25

本文共 4101 字,大约阅读时间需要 13 分钟。

iOS开发多线程篇—线程安全

 

一、多线程的安全隐患

资源共享

1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源

比如多个线程访问同一个对象、同一个变量、同一个文件

当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题

示例一:

示例二:

问题代码:

8  9 10 #import "YYViewController.h"11 12 @interface YYViewController ()13 //剩余票数14 15 @property(nonatomic,assign) int leftTicketsCount;16 @property(nonatomic,strong)NSThread *thread1;17 @property(nonatomic,strong)NSThread *thread2;18 @property(nonatomic,strong)NSThread *thread3;19 20 21 @end22 23 24 @implementation YYViewController25 26 27 - (void)viewDidLoad28 {29     [super viewDidLoad];30 31     //默认有20张票32 33     self.leftTicketsCount=10;34 35     //开启多个线程,模拟售票员售票36 37     self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];38 39     self.thread1.name=@"售票员A";40 41     self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];42 43     self.thread2.name=@"售票员B";44 45     self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];46     self.thread3.name=@"售票员C";47 }48 49  50 -(void)sellTickets51 {52     while (1) {53         //1.先检查票数54         int count=self.leftTicketsCount;55         if (count>0) {56             //暂停一段时间57             [NSThread sleepForTimeInterval:0.002];58 59             //2.票数-160            self.leftTicketsCount= count-1;61  62             //获取当前线程63             NSThread *current=[NSThread currentThread];64             NSLog(@"%@--卖了一张票,还剩余%d张票",current,self.leftTicketsCount);65         }else66         {67             //退出线程68             [NSThread exit];69         }70     }71 }72 73 74 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event75 { 76     //开启线程77 78    [self.thread1 start];79     [self.thread2 start];80     [self.thread3 start];81 82 }83 84 @end

 

打印结果:

 

二、安全隐患分析

 

 

三、如何解决

 

互斥锁使用格式

@synchronized(锁对象) { // 需要锁定的代码  }

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

 

代码示例:

8  9 #import "YYViewController.h"10 11 @interface YYViewController ()12 13 //剩余票数14 @property(nonatomic,assign) int leftTicketsCount;15 @property(nonatomic,strong)NSThread *thread1;16 @property(nonatomic,strong)NSThread *thread2;17 @property(nonatomic,strong)NSThread *thread3;18 @end19 20 @implementation YYViewController21 22 - (void)viewDidLoad23 {24     [super viewDidLoad];25     //默认有20张票26     self.leftTicketsCount=10;27     //开启多个线程,模拟售票员售票28 29     self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];30 31     self.thread1.name=@"售票员A";32 33     self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];34 35     self.thread2.name=@"售票员B";36 37     self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];38 39     self.thread3.name=@"售票员C";40 }41 42 43 -(void)sellTickets44 {45     while (1) {46         @synchronized(self){//只能加一把锁47         //1.先检查票数48 49         int count=self.leftTicketsCount;50         if (count>0) {51             //暂停一段时间52             [NSThread sleepForTimeInterval:0.002];53             //2.票数-154 55            self.leftTicketsCount= count-1;56             //获取当前线程57             NSThread *current=[NSThread currentThread];58             NSLog(@"%@--卖了一张票,还剩余%d张票",current,self.leftTicketsCount);59 60         }else61         {62             //退出线程63             [NSThread exit];64         }65         }66     }67 }68 69 70 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event71 {72 73     //开启线程74    [self.thread1 start];75     [self.thread2 start];76     [self.thread3 start];77 }78 79 @end

执行效果图

 

互斥锁的优缺点

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

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

 

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

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

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

 

四:原子和非原子属性

 

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

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

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

 

atomic加锁原理

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

 

原子和非原子属性的选择

nonatomic和atomic对比

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

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

 

iOS开发的建议

所有属性都声明为nonatomic

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

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

 

 
 

转载于:https://www.cnblogs.com/crash-wu/p/4806499.html

你可能感兴趣的文章
nodejs在linux环境下安装更新方式
查看>>
大道至简-第二章 心得体会
查看>>
湖南多校对抗赛(2015.05.03)Problem B: War
查看>>
hdu 3986 Harry Potter and the Final Battle
查看>>
NYIST OJ 题目20 吝啬的王国
查看>>
在500jsp错误页面获取错误信息
查看>>
python常见示例->web简单示例
查看>>
centos7下安装部署mongodb集群(副本集模式)
查看>>
[BZOJ] 1334: [Baltic2008]Elect
查看>>
Jquery对象---Jquery API (2)
查看>>
PHP ReflectionClass
查看>>
swift历史
查看>>
mysql导入大量数据时报MySQL server has gone away错误的解决办法
查看>>
socket简单理解
查看>>
过滤HTML
查看>>
临时表 表变量 游标
查看>>
关于 iTunes Store 授权和取消授权
查看>>
React文档(十三)思考React
查看>>
公司部门和职位
查看>>
python内置函数中的map,filter,reduce函数例子
查看>>