设为首页 加入收藏

TOP

iOS多线程技术方案(五)
2017-10-12 18:08:09 】 浏览:7270
Tags:iOS 线程 技术 方案
1:78688] 18--<NSThread: 0x7fead2017f30>{number = 2, name = test1} 2016-02-16 22:43:28.185 05-线程状态[1241:78689] 9--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.185 05-线程状态[1241:78688] 19--<NSThread: 0x7fead2017f30>{number = 2, name = test1} 2016-02-16 22:43:28.185 05-线程状态[1241:78689] 10--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.186 05-线程状态[1241:78689] 11--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.186 05-线程状态[1241:78689] 12--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.186 05-线程状态[1241:78689] 13--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.186 05-线程状态[1241:78689] 14--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.187 05-线程状态[1241:78689] 15--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.187 05-线程状态[1241:78689] 16--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.187 05-线程状态[1241:78689] 17--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.187 05-线程状态[1241:78689] 18--<NSThread: 0x7fead050a250>{number = 3, name = test2} 2016-02-16 22:43:28.187 05-线程状态[1241:78689] 19--<NSThread: 0x7fead050a250>{number = 3, name = test2}

结论六:优先级高,不一定先执行,只能说明先执行的概率要大一些!!!


四、互斥锁

1、访问共享资源引入问题!

1.1 问题?

不同的线程要访问共享的资源,而且对共享的资源做操作,由于上面结论六得出服务质量和优先级不能决定线程执行的先后顺序,那么问题来了,一个线程对共享资源做了修改,而另外一个线程拿到的是未被修改之前资源,这是这个线程也对该资源做了修改,现在请问,两个线程都对该资源做了不同的修改,那么这个修改应该算谁的?!?!这就是问题所在!!!

1.2 问题分析

1

1.3 问题解决

1
这个文档里盗的图!

解决方案很简单,就是用一把锁锁住共享资源,等待线程1对其操作完毕后再打开,让线程2来执行,这就是传说中的互斥锁!!!

2、互斥锁介绍

2.1 互斥锁代码

@synchronized(锁对象) { 需要锁定的代码  }

2.2 互斥锁的作用

可以防止因多线程执行顺序不定导致的抢夺资源造成的数据安全的问题

2.3 真相:互斥锁其实就是同步的意思,也就是按顺序执行!

3、互斥锁原理

每个NSObject对象内部都有一把锁,当线程要进入synchronized到对象的时候就要判断,锁是否被打开,如果打开,进入执行,如果锁住,继续等待,这就是互斥锁的原理!

4、互斥锁和自旋锁

自旋锁就是atomic!

4.1 原子属性和非原子属性(nonatomic 和 atomic)

  • nonatomic:非原子属性,不会为 setter 方法加锁。
  • atomic: 原子属性,为 setter 方法加锁(默认就是atomic)。
    • 通过给 setter 加锁,可以保证同一时间只有一个线程能够执行写入操作(setter),但是同一时间允许多个线程执行读取操作(getter)。atomic本身就有一把自旋锁。
      这个特点叫做”单写多读”: 单个线程写入,多个线程读取。
    • atomic 只能保证写入数据的时候是安全的,但不能保证同时读写的时候是安全的。所以,不常使用!

4.2 nonatomic 和 atomic 的对比

atomic:线程安全(执行setter方法的时候),需要消耗大量的资源。

nonatomic:非线程安全,适合内存小的移动设备。

4.3 互斥锁和自旋锁的区别

互斥锁

如果发现其它线程正在执行锁定代码,线程会进入休眠(阻塞状态),等其它线程时间片到了打开锁后,线程就会被唤醒(执行)。

自旋锁

如果发现有其它线程正在执行锁定代码,线程会以死循环的方式,一直等待锁定的代码执行完成。
***

五、GCD

1、GCD介绍

全称Grand Central Dispatch,可翻译为”牛逼的中枢调度器”

C语言开发,是苹果公司为多核的并行运算提出的解决方案,会自动利用更多的CPU内核(比如双核、四核),可以自动管理线程的生命周期(创建线程、调度任务、销毁线程)。

2、GCD的两个核心

2.1 任务

  • 执行的操作,在GCD中,任务是通过 block来封装的。并且任务的block没有参数也没有返回值。

2.2 队列

  • 存放任务

包括

  • 串行队列
  • 并发队列
  • 主队列
  • 全局队列

队列的类型
1

3、函数

3.1 GCD函数

3.1.1 同步 dispatch_sync

同步:任务会在当前线程执行,因为同步函数不具备开新线程的能力。
void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

3.1.2 异步 dispatch_async

异步:任务会在子线程执行,因为异步函数具备开新线程的能力。
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

3.2 GCD使用步骤:

  • 创建队列,或则获取队列
  • 创建任务
  • 将任务添加到队列中
    • GCD会自动将队列中的任务取出,放到对应的线程中执行
    • 任务取出遵循队列的FIFO原则:先进先出,后进后出

示例代码

// 1. 获取全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 2. 创建任务
dispatch_block_t task = ^ {
    NSLog(@"hello %@", [NSThread curre
首页 上一页 2 3 4 5 6 7 8 下一页 尾页 5/9/9
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇基于OpenSSL的RSA加密应用(非算法) 下一篇在uiview里面的tableView中,点击..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目