一、多线程的安全隐患

资源共享

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

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

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

示例一:

示例二:

问题代码:

 1 //2 //  YYViewController.m3 //  05-线程安全4 //5 //  Created by apple on 14-6-23.6 //  Copyright (c) 2014年 itcase. All rights reserved.7 //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 @end
22
23
24 @implementation YYViewController
25
26
27 - (void)viewDidLoad
28 {
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)sellTickets
51 {
52     while (1) {
53         //1.先检查票数
54         int count=self.leftTicketsCount;
55         if (count>0) {
56             //暂停一段时间
57             [NSThread sleepForTimeInterval:0.002];
58
59             //2.票数-1
60            self.leftTicketsCount= count-1;
61
62             //获取当前线程
63             NSThread *current=[NSThread currentThread];
64             NSLog(@"%@--卖了一张票,还剩余%d张票",current,self.leftTicketsCount);
65         }else
66         {
67             //退出线程
68             [NSThread exit];
69         }
70     }
71 }
72
73
74 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
75 {
76     //开启线程
77
78    [self.thread1 start];
79     [self.thread2 start];
80     [self.thread3 start];
81
82 }
83
84 @end

打印结果:

二、安全隐患分析

三、如何解决

互斥锁使用格式

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

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

代码示例:

 1 //2 //  YYViewController.m3 //  05-线程安全4 //5 //  Created by apple on 14-6-23.6 //  Copyright (c) 2014年 itcase. All rights reserved.7 //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 @end
19
20 @implementation YYViewController
21
22 - (void)viewDidLoad
23 {
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)sellTickets
44 {
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.票数-1
54
55            self.leftTicketsCount= count-1;
56             //获取当前线程
57             NSThread *current=[NSThread currentThread];
58             NSLog(@"%@--卖了一张票,还剩余%d张票",current,self.leftTicketsCount);
59
60         }else
61         {
62             //退出线程
63             [NSThread exit];
64         }
65         }
66     }
67 }
68
69
70 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
71 {
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)age
4 {
5
6     @synchronized(self) {
7        _age = age;
8     }
9 }

原子和非原子属性的选择

nonatomic和atomic对比

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

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

iOS开发的建议

所有属性都声明为nonatomic

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

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

转载于:https://www.cnblogs.com/LifeTechnologySupporter/p/10353096.html

iOS开发多线程篇—线程安全相关推荐

  1. iOS开发多线程篇—线程的状态

    iOS开发多线程篇-线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(te ...

  2. iOS开发多线程篇—多线程简介

    iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xc ...

  3. iOS开发多线程篇—自定义NSOperation

    iOS开发多线程篇-自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...

  4. iOS开发——高级篇——线程同步、线程依赖、线程组

    前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查 ...

  5. iOS开发多线程篇—多线程简单介绍

    一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过& ...

  6. iOS开发——多线程篇——GCD

    一.基本概念 1.简介 什么是GCD 全称是Grand Central Dispatch,可译为"牛逼的中枢调度器" 纯C语言,提供了非常多强大的函数 GCD的优势 GCD是苹果公 ...

  7. ios开发多线程篇--异步加载网络图片GCD

    一.异步加载网络图片 1.ATS (1)简介 从iOS9.0开始,如果按照以前的方式写代码,在访问网络的时候 ,会报以下警告信息: App Transport Security has blocked ...

  8. iOS开发网络篇—多线程断点下载

    iOS开发网络篇-多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  9. iOS开发里的线程安全机制

    [编者按]本文为再读苹果<Threading Programming Guide>笔记第四篇,主要分享了线程安全机制以及设计时所需要注意的事项.从最初的"什么是线程"到 ...

最新文章

  1. Ehcache的基本概念
  2. 宝塔安装php遇错libicui18n.so.42: cannot open shared object file: No such file or directory
  3. 云计算到底是谁发明的?
  4. 父子组建传值_浅谈Vue父子组件和非父子组件传值问题
  5. php取整函数ceil,floor,round,intval函数的区别
  6. QML笔记-对QML中信号与槽的进一步认识
  7. oracle有三种类型的异常错误: 预定义 ( Predefined )错误里面的常见错误
  8. Python操作SQLServer示例
  9. 手把手教你搭建FastDFS集群(上)
  10. DFA算法实现 敏感词过滤
  11. 易语言 精易模块 网页_访问 获取显示验证码图片
  12. 百度搜索下拉框,下拉菜单怎么做?如何刷?
  13. 街头霸王5显示正在登陆服务器无法进入游戏,街头霸王5打不开怎么办 无法进入游戏解决方法...
  14. Java类的继承学生研究生类图_UML part3 类图、对象图
  15. qt开发之获取鼠标的相对位置和绝对位置
  16. [蓝桥杯2022初赛] 砍竹子
  17. JRebel热部署,从此告别一遍一遍重启项目
  18. 在知识蒸馏中不要忘记教师网络detach()
  19. Cris 的Python笔记(六):函数基础
  20. 撤销和重做实现-第二部分(命令模式)

热门文章

  1. js图片轮换显示实例(转载)
  2. 基于SSM实现绿色有机产品直营网
  3. Intellij IDEA设置运行时Java参数
  4. 正则 去除字符串中的特殊字符
  5. bzoj1624:[Usaco2008 Open] Clear And Present Danger 寻宝之路
  6. 北京集训:20180323
  7. Java之 javaObject与jsonString的转换
  8. Redis在windows实现将数据缓存起来定时更新读取
  9. XShell与虚拟机连接的IP问题
  10. Object:window_方法