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

简介: iOS开发多线程篇—线程安全   一、多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象、同一个变量、同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题 示例一: 示例二: 问题代码: 1 // 2 // YYViewController.

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

 

一、多线程的安全隐患

资源共享

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

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

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

示例一:

示例二:

问题代码:

 1 //
 2 //  YYViewController.m
 3 //  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.m
 3 //  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在定义属性时有nonatomicatomic两种选择

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 }

 

原子和非原子属性的选择

nonatomicatomic对比

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

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

 

iOS开发的建议

所有属性都声明为nonatomic

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

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

目录
相关文章
|
5天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
13天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
34 9
|
9天前
|
设计模式 Swift iOS开发
探索iOS开发:从基础到高级,打造你的第一款App
【10月更文挑战第40天】在这个数字时代,掌握移动应用开发已成为许多技术爱好者的梦想。本文将带你走进iOS开发的世界,从最基础的概念出发,逐步深入到高级功能实现,最终指导你完成自己的第一款App。无论你是编程新手还是有志于扩展技能的开发者,这篇文章都将为你提供一条清晰的学习路径。让我们一起开始这段旅程吧!
|
12天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
10天前
|
iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第39天】在苹果的生态系统中,SwiftUI框架以其声明式语法和易用性成为开发者的新宠。本文将深入SwiftUI的核心概念,通过实际案例展示如何利用这一框架快速构建用户界面,并探讨其对iOS应用开发流程的影响。
|
13天前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
18天前
|
设计模式 前端开发 Swift
探索iOS开发:从初级到高级的旅程
【10月更文挑战第31天】在这篇文章中,我们将一起踏上iOS开发的旅程。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。我们将从基础开始,逐步深入到更高级的技术和概念。让我们一起探索iOS开发的世界吧!
|
21天前
|
设计模式 前端开发 Swift
探索iOS开发:从初级到高级的旅程
【10月更文挑战第28天】在这篇技术性文章中,我们将一起踏上一段探索iOS开发的旅程。无论你是刚入门的新手,还是希望提升技能的开发者,这篇文章都将为你提供宝贵的指导和灵感。我们将从基础概念开始,逐步深入到高级主题,如设计模式、性能优化等。通过阅读这篇文章,你将获得一个清晰的学习路径,帮助你在iOS开发领域不断成长。
57 2
|
26天前
|
安全 API Swift
探索iOS开发中的Swift语言之美
【10月更文挑战第23天】在数字时代的浪潮中,iOS开发如同一艘航船,而Swift语言则是推动这艘船前进的风帆。本文将带你领略Swift的独特魅力,从语法到设计哲学,再到实际应用案例,我们将一步步深入这个现代编程语言的世界。你将发现,Swift不仅仅是一种编程语言,它是苹果生态系统中的一个创新工具,它让iOS开发变得更加高效、安全和有趣。让我们一起启航,探索Swift的奥秘,感受编程的乐趣。
|
29天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
19 3