一、iOS中的多线程
- 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块)
- iOS中多线程的实现方案有以下几种
二、NSThread线程类的简单实用(直接上代码)
三、多线程的安全隐患
- 资源共享
- 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源
- 比如多个线程访问同一个对象、同一个变量、同一个文件
- 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题(存钱取钱的例子,多个售票员卖票的例子)
- 安全隐患解决的方法 --- 互斥锁(图解)
- 互斥锁简单介绍
- 售票员卖票例子的代码实现
#import "ViewController.h" @interface ViewController ()
/** Thread01 */
@property(nonatomic,strong) NSThread *thread01;
/** Thread02 */
@property(nonatomic,strong) NSThread *thread02;
/** Thread03 */
@property(nonatomic,strong) NSThread *thread03;
/** ticketCount */
@property(nonatomic,assign) NSInteger ticketCount;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; self.ticketCount = ; // 线程创建之后不执行start 出了大括号会被销毁,所以这里用成员变量存了起来
self.thread01 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread01.name = @"售票员01";
self.thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread02.name = @"售票员02";
self.thread03 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread03.name = @"售票员03";
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self.thread01 start];
[self.thread02 start];
[self.thread03 start]; } - (void)saleTicket
{
@synchronized(self) { // 添加互斥锁,括号中的什么对象都可以,但是必须是同一个! while () {
// 取出剩余票总数
NSInteger count = self.ticketCount;
if (count > ) {
self.ticketCount = count - ;
NSLog(@"%@卖出了车票,还剩%ld",[NSThread currentThread].name,self.ticketCount);
} else { NSLog(@"%@把车票卖完了",[NSThread currentThread].name);
break;
} }
}
} @end
- 不加互斥锁打印的结果如图:
四、原子和非原子属性--atomic、nonatomic
五、线程之间的通信(练习:下载图片的练习)