多线程
科普
问题:线程不安全一定crash么? 线程不安全可能crash么?
答案: 不一定 ,可能
线程安全 就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能访问直到该线程读取完,其他线程才可使用,不会出现数据不一致或数据污染
线程不安全 就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据时脏数据
如果你的代码所在的进程中有多个线程同时运行,而这些线程可能同时运行这段代码,如果每次运行结果和单线程运行结果是一样的,而且其他变量的值也和预期是一样的,就是线程安全的
【多线程】线程安全问题都是由于全局变量和静态变量引起的
若每个线程对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能印象线程安全
参考链接:
https://blog.csdn.net/ghevinn/article/details/37764791
- 数组线程不安全不crash eg
self.array = [NSMutableArray array];
self.arrayConcurrencyQueue = dispatch_queue_create("com.sohu.qq", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_queue_create("com.sohu.sync", DISPATCH_QUEUE_CONCURRENT);
for ( int i =0;
i < 100;
i++) {
dispatch_async(self.arrayConcurrencyQueue, ^{
//[self addObject:[NSNumber numberWithInteger:i]];
//[self printCount];
[self.array addObject:[NSNumber numberWithInteger:i]];
NSLog(@"dispatch_async self.arrayCount:%zd",self.array.count);
});
}
执行结果不crash
文章图片
image.png
- 非线程安全crash
self.array = [NSMutableArray array];
self.arrayConcurrencyQueue = dispatch_queue_create("com.sohu.qq", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_queue_create("com.sohu.sync", DISPATCH_QUEUE_CONCURRENT);
for ( int i =0;
i < 100;
i++) {
dispatch_async(self.arrayConcurrencyQueue, ^{
//[self addObject:[NSNumber numberWithInteger:i]];
//[self printCount];
[self.array insertObject:[NSNumber numberWithInteger:i] atIndex:i];
NSLog(@"dispatch_async self.arrayCount:%zd",self.array.count);
});
}
NSLog(@"for after self.arrayCount:%zd",self.array.count);
结果:
文章图片
image.png
- 数组线程安全eg
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.- ()
self.array = [NSMutableArray array];
self.arrayConcurrencyQueue = dispatch_queue_create("com.sohu.qq", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_queue_create("com.sohu.sync", DISPATCH_QUEUE_CONCURRENT);
for ( int i =0;
i < 100;
i++) {
dispatch_async(queue, ^{
[self addObject:[NSNumber numberWithInteger:i]];
[self printCount];
});
}
NSLog(@"for after self.arrayCount:%zd",self.array.count);
//TODO 小结 引发对线程安全的理解线程安全定义重新查看线程安全 != Crash
}- (void)addObject:(id)object{
dispatch_barrier_async(self.arrayConcurrencyQueue, ^{
[self.array addObject:object];
});
}- (void)printCount{
dispatch_async(self.arrayConcurrencyQueue, ^{
NSLog(@"dispatch_async self.arrayCount:%zd",self.array.count);
});
}
原理:
文章图片
image.png 扩展:写一个线程安全的NSMutableArray子类,未完待续
问题:
1、
__block int a= 0;
//1
while (a < 10) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
a++;
NSLog(@"%@---%d",[NSThread currentThread],a);
});
NSLog(@"while-after:%@---%d",[NSThread currentThread],a);
}
NSLog(@"终于等到你:%d",a);
2dispatch_get_main 官方注释理解main函数的关系 与runLoop 自动释放池的关系
3 、创建线程安全的可变数组
4、
文章图片
image.png
给出答案
5、栅栏函数不能用系统的globalQueue
6、为啥画UI要在主线程 离屏渲染
7、
for ( int i = 0; i < 100; i++) {
dispatch_async(self.arrayConcurrencyQueue, ^{
// [self addObject:[NSNumber numberWithInteger:i]];
// [self printCount];
@synchronized (self) {
[self.array addObject:[NSNumber numberWithInteger:i]];
}
NSLog(@"dispatch_async self.arrayCount:%zd",self.array.count);
});
}
以上代码,为啥同步锁不起作用?换成 self.lock = [[NSLock alloc] init]; 依然不起作用为啥?
推荐阅读
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 爱就是希望你好好活着
- 昨夜小楼听风
- 知识
- 死结。
- 我从来不做坏事
- 烦恼和幸福
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- Linux下面如何查看tomcat已经使用多少线程
- 说得清,说不清