标签:等于 被锁 产生 control get com 写文件 color 过程
在多线程学习中,必然会涉及到不同线程对同一资源的调取,面对这种调用不加以控制,就会产生数据混乱的情况。最常见的情况莫过于买票,多个售票员售票肯定是同时操作,这样就会开启多条线程,但是这种售票方式会产生票数不对的情况。
- (void)demo1 { //售票员A NSThread *threadA = [[NSThread alloc] initWithTarget:self selector:@selector(sellTikets) object:nil]; threadA.name = @"threadA"; [threadA start]; //售票员B NSThread *threadB = [[NSThread alloc] initWithTarget:self selector:@selector(sellTikets) object:nil]; threadB.name = @"threadB"; [threadB start]; } - (void)sellTikets{ while (YES) { if (self.tiketNum > 0) { self.tiketNum -- ; NSLog(@"还剩%d张票 %@",self.tiketNum,[NSThread currentThread]); }else { NSLog(@"票卖完了 %@",[NSThread currentThread]); break; } } }
这里对于第九张票出售了两次,这就是用多线程产生的数据不安全问题,因为在多线程的资源共享中,就得上一把锁来保证不会出现这种问题
- (void)sellTikets{ while (YES) { @synchronized(self) { if (self.tiketNum > 0) { self.tiketNum -- ; NSLog(@"还剩%d张票 %@",self.tiketNum,[NSThread currentThread]); }else { NSLog(@"票卖完了 %@",[NSThread currentThread]); break; } } } }
@syn中需要传一个全局变量参数,不一定是self,但是一定不能传一个局部变量,因为这里的参数作为一个锁,要保证在线程执行的整个过程中都能锁住线程,如果是一个局部变量,线程运行一次就被释放掉了,根本毫无意义。
互斥锁保证了线程在运行中,每次只有一个线程能访问到被锁住的代码块,其他需要访问的线程则在锁外面睡眠等待,当一个线程执行完毕,才有下一个线程的执行。那么,我们就得提到OC中的另外一个概念,原子性 atomic。在变量的声明时,我们大多是情况下都是用nonatomic,用以提高运行效率,那么atomic的作用在哪里呢?一般我们在写文件的时候,会使用这样的代码:
NSData*data = [@"iosSynChronized" dataUsingEncoding:NSUTF8StringEncoding]; [data writeToFile:@"ios.text" atomically:YES];
为了保证文件写入时候的安全,我们一般会选择使用原子性。这样,当文字在写入的时候并不是直接创建一个本地文件写数据,而是创建一个虚拟文件,当数据写入完成,然后一次性形成要存储的本地文件,就不会出现,写入的时候你删除文件,修改文件造成的数据冲突。类似于一个锁一样,锁住你要操作的东西,只有完成才能结束。同样,给变量声明atomic也就等于给变量赋值创建了一把锁,只有一个线程完成对该变量的操作,下一个线程才能进行:
@property (atomic, strong) NSObject *lock; @end @implementation ViewController @synthesize lock = _lock;//重新getter和setter方法后,xcode就不会自动帮写成员变量 -(void)setLock:(NSObject *)lock { @synchronized (self) { _lock = lock; } } - (NSObject *)lock { return _lock;
锁能够保证数据安全,但同样也因此带来了极大的不便,那就是效率问题,它将所有访问操作都变成了单一操作,会浪费大量时间,这也是苹果的UIKIT同样采用线程不安全方式的原因,考虑到了效率问题。
标签:等于 被锁 产生 control get com 写文件 color 过程
原文地址:http://www.cnblogs.com/zhulilove/p/7809089.html