1. NSThread是相对GCD和NSOperationQuene而言
比较轻量级的一种多线程处理方式。
它的弊端就是需要自己管理线程的生命周期,以及线程同步;
而另外两种不需要自己管理。
2.有一个场景:有关多人售票的问题
多个线程开启,来争取资源。会出现线程不安全的问题。
线程不安全造成的原因:(在我有限的知识范围)就是多线程造成的。
为什么这么说的呢? 多个线程访问公共的资源,有的写操作,有的读操作,
这样子可能出现的结果:数据不统一,数据错乱。
可能就是我们的需求:对这块公共的数据既要读操作,又要写操作,由于要充分理由cpu和资源的利用率,(程序要跑得快),会进行并发操作,它们就会存在资源竞争的这种关系。这导致和我们预测的结果大不相同。
一般这样子的情况:会进行加锁处理或者其他的解决方案
比如:NSThread场景:
多个售票员卖票,剩余的票数,争夺一大块数据中的一个。会出现线程不安全的情况
代码:
定义一个总票数: NSInteger _ticketCount;
_ticketCount = 17 *4;
- (void)sailTicket {
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
NSThread *thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
thread1.name = @"售票员1";
thread2.name = @"售票员2";
thread3.name = @"售票员3";
[thread1 start];
[thread2 start];
[thread3 start];
signal = dispatch_semaphore_create(1);
}
1).@synchronized (self) {}
-(void)sale{
while (1) {
@synchronized (self) {
for (int i = 0; i<10000; i++) {
//模拟延迟
}
if (_ticketCount>0){
_ticketCount--;
NSLog(@"%@卖出了一张票,余票还有%lu",[NSThread currentThread].name,(unsigned long)_ticketCount);
}else{
NSLog(@"票已售完");
break;
}
}
}
}
运行的结果:可以解决线程不安全的问题

2).NSLock
//主线程中,声明一把锁
NSLock *lock = [NSLock new];
-(void)sale{
[lock lock];
while (1) {
for (int i = 0; i<10000; i++) {
//模拟延迟
}
if (_ticketCount>0){
_ticketCount--;
NSLog(@"%@卖出了一张票,余票还有%lu",[NSThread currentThread].name,(unsigned long)_ticketCount);
}else{
NSLog(@"票已售完");
break;
}
}
[lock unlock];
}
运行的结果:

3.信号量
dispatch_semaphore_t signal = dispatch_semaphore_create(1);
while (1) {
//3.信号量
// NSLog(@"%@_create:%ld",[NSThread currentThread].name,i);
i = dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
//此时信号量为0 对signal增加1 信号量变为1,
// NSLog(@"%@_wait:%ld",[NSThread currentThread].name,i);
for (int i = 0; i<10000; i++) {
//模拟延迟
}
if (_ticketCount>0){
_ticketCount--;
NSLog(@"%@卖出了一张票,余票还有%lu",[NSThread currentThread].name,(unsigned long)_ticketCount);
}else{
NSLog(@"票已售完");
break;
}
i = dispatch_semaphore_signal(signal);
// NSLog(@"%@_signal:%ld",[NSThread currentThread].name,i);
}
运行结果:这样子写更加随机点

网友评论