当多个线程同时访问同一块资源时,会造成资源的读写错误,意思就是同一个文件,同时有人在读,又有人在写入,肯定是要出错的,那么这就涉及到线程安全,线程安全我们使用互斥锁来防止,代码如下
#import "ViewController.h"
@interface ViewController ()
/** A */
@property (nonatomic, strong) NSThread *threadA;
/** B */
@property (nonatomic, strong) NSThread *threadB;
/** C */
@property (nonatomic, strong) NSThread *threadC;
@property (nonatomic, assign) NSInteger totalCount;
@end
@implementation ViewController
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//设置中票数
self.totalCount = 100;
self.threadA = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
self.threadB = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
self.threadC = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
self.threadA.name = @"A";
self.threadB.name = @"B";
self.threadC.name = @"C";
//启动线程
@synchronized(self) {
[self.threadA start];
[self.threadB start];
[self.threadC start];
}
}
-(void)saleTicket
{
while (1) {
//锁:必须是全局唯一的
//1.注意枷锁的位置
//2.注意枷锁的前提条件,多线程共享同一块资源
//3.注意加锁是需要代价的,需要耗费性能的
//4.加锁的结果:线程同步
@synchronized(self) {
//线程1
//线程2
//线程3
NSInteger count = self.totalCount;
if (count >0) {
for (NSInteger i = 0; i<1000000; i++) {
}
self.totalCount = count - 1;
//卖出去一张票
NSLog(@"%@卖出去了一张票,还剩下%zd张票", [NSThread currentThread].name,self.totalCount);
}else
{
NSLog(@"不要回公司上班了");
break;
}
}
}
}
@end
- 我们在创建单列时有时候为了考虑线程安全的问题,也会使用互斥锁
static PayManager *_instance = nil;
/**
* alloc 方法内部会调用这个方法
*/
+(id)allocWithZone:(struct _NSZone *)zone{
if (_instance == nil) {//防止频繁加锁
@synchronized(self) {
if (_instance == nil) {//防止创建多次
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
/**
* 实例化类
*/
+(instancetype)sharedMusicTool{
if (_instance == nil) {//防止频繁枷锁
@synchronized(self) {
if (_instance == nil) {//防止创建多次
_instance = [[self alloc] init ];
}
}
}
return _instance;
}
/**
* 重写copy方法,保证copy出来的也是单例类
*/
-(id)copyWithZone:(NSZone *)zone{
return _instance;
}
网友评论