一、iOS中的多线程
- 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块)
- iOS中多线程的实现方案有以下几种
二、NSThread线程类的简单实用(直接上代码)
三、多线程的安全隐患
- 资源共享
-
- 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源
-
- 比如多个线程访问同一个对象、同一个变量、同一个文件
- 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题(存钱取钱的例子,多个售票员卖票的例子)
- 安全隐患解决的方法 --- 互斥锁(图解)
- 互斥锁简单介绍
- 售票员卖票例子的代码实现
1 #import "ViewController.h" 2 3 @interface ViewController () 4 /** Thread01 */ 5 @property(nonatomic,strong) NSThread *thread01; 6 /** Thread02 */ 7 @property(nonatomic,strong) NSThread *thread02; 8 /** Thread03 */ 9 @property(nonatomic,strong) NSThread *thread03; 10 /** ticketCount */ 11 @property(nonatomic,assign) NSInteger ticketCount; 12 @end 13 14 @implementation ViewController 15 16 - (void)viewDidLoad { 17 [super viewDidLoad]; 18 19 self.ticketCount = 100; 20 21 // 线程创建之后不执行start 出了大括号会被销毁,所以这里用成员变量存了起来 22 self.thread01 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; 23 self.thread01.name = @"售票员01"; 24 self.thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; 25 self.thread02.name = @"售票员02"; 26 self.thread03 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; 27 self.thread03.name = @"售票员03"; 28 } 29 30 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 31 32 [self.thread01 start]; 33 [self.thread02 start]; 34 [self.thread03 start]; 35 36 } 37 38 - (void)saleTicket 39 { 40 @synchronized(self) { // 添加互斥锁,括号中的什么对象都可以,但是必须是同一个! 41 42 while (1) { 43 // 取出剩余票总数 44 NSInteger count = self.ticketCount; 45 if (count > 0) { 46 self.ticketCount = count - 1; 47 NSLog(@"%@卖出了车票,还剩%ld",[NSThread currentThread].name,self.ticketCount); 48 } else { 49 50 NSLog(@"%@把车票卖完了",[NSThread currentThread].name); 51 break; 52 } 53 54 } 55 } 56 } 57 58 @end
- 不加互斥锁打印的结果如图:
四、原子和非原子属性--atomic、nonatomic
五、线程之间的通信(练习:下载图片的练习)