1、多线程的概念

Multithreading多线程是指从软件或硬件上,实现多个线程并发执行的技术。使得能够同步完成多项任务,提高资源使用效率。

1.1 任务、进程和线程

  • 任务Task:应用程序完成的一个活动,一个task既可以是一个进程,也可以是一个线程;
  • 进程Process:系统进行资源分配和调度的一个独立单位,在内存中有完备的数据空间和代码空间;
  • 线程Thread:进程中的一个实体,CPU调度和分派的基本单位;

1.2 线程的Stack space

系统中每一个进程都有自己的内存空间,同个进程中多个线程共用进程的内存空间。

  • 在Mac OS中,主线程的栈空间为8MB;
  • 在Ios中,主线程的栈空间为1MB;

应用程序子线程默认栈空间大小为512KB,子线程允许分配的最小栈空间为16KB,并且必须是4KB的整数倍。开发者可以通过NSThread线程对象的stacksize来修改一个子线程的栈空间。

let thread = Thread.init(target: self, selector:(VIewController.threadAction),object:nil)
thread.stackSize = 1024*1024

1.3 线程的优先级

  • threadPriority: 0.0-1.0
  • 系统默认优先级是0.5
  • 高优先级并不是100%比低优先级先执行,只是得到CPU调度的纪律更高
1.4 线程的生命周期
  • 创建 对线程对象进行初始化;
  • 就绪 添加到线程池,等待CPU的调度;
  • 运行 是线程处于执行状态;
  • 阻塞 可以是线程休眠至指定的时间点,或者通过Lock给线程加锁;
  • 消亡 执行完毕之后自动处于正常消亡状态;
2、三种常用的多线程技术
2.1 Thread

var imageView = UIImageView()
var label = UILabel() override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imageView = UIImageView(frame: CGRect(x: 0, y: 120, width: 320, height: 300))
self.view.addSubview(imageView) label = UILabel(frame: CGRect(x: 0, y: 120, width: 320, height: 300))
label.backgroundColor = UIColor.lightGray
label.textAlignment = .center
label.text = "Loading..."
label.font = UIFont.systemFont(ofSize: 42)
self.view.addSubview(label) let imageUrl = "http://images.apple.com/v/iphone/home/s/home/images/trade_in_iphone_large_2x.jpg"
let thread = Thread(target: self, selector: #selector(ViewController.downloadImage), object: imageUrl)
thread.start()
} func downloadImage(path : String){
let url = URL(string: path)
var data : Data!
do{
try data = Data(contentsOf: url!)
let image = UIImage(data: data)
self.perform(#selector(ViewController.showImage), on: Thread.main, with: image, waitUntilDone: true)
}catch{
print("下载图片失败。")
}
} func showImage(image : UIImage){
self.imageView.image = image
self.label.isHidden = true
}


2.2 Operation
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
topImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 320, height: 280))
self.view.addSubview(topImageView) footImageView = UIImageView(frame: CGRect(x: 0, y: 280, width: 320, height: 290))
self.view.addSubview(footImageView) let downloadA = getOperation(name: "下载线程A", imageUrl: "http://images.apple.com/v/watch/k/images/overview/watch_03_large.jpg", isTopOne: true) let downloadB = getOperation(name: "下载线程B", imageUrl: "http://images.apple.com/v/watch/k/images/overview/watch_05_large.jpg", isTopOne: false) let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
queue.addOperation(downloadA)
queue.addOperation(downloadB) for operation in queue.operations{
print("Operation名称:"+operation.name!)
}
} func getOperation(name : String, imageUrl : String, isTopOne : Bool) -> BlockOperation{
let download = BlockOperation(block: {_ in
let url = URL(string: imageUrl)
var data : Data!
do{
Thread.sleep(forTimeInterval: 1.0)
try data = Data(contentsOf: url!)
let image = UIImage(data: data)
if isTopOne{
self.perform(#selector(ViewController.showTopImage), on: Thread.main, with: image, waitUntilDone: true)
}
else{
self.perform(#selector(ViewController.showFootImage), on: Thread.main, with: image, waitUntilDone: true)
}
}catch{
print("下载图片失败。")
}
})
download.name = name
return download
} func showTopImage(image : UIImage){
self.topImageView.image = image
} func showFootImage(image : UIImage){
self.footImageView.image = image
}



2.3 Grand Central Dispatch
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
label.frame = CGRect(x: 0, y: 0, width: 320, height: 568)
label.text = "Loading..."
label.font = UIFont(name: "Arial", size: 24)
label.backgroundColor = UIColor.orange
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
self.view.addSubview(label) let apiURL = URL(string: "http://ip.taobao.com/service/getIpInfo.php?ip=27.156.152.57") let globalQueue = DispatchQueue.global()
globalQueue.async{
let result = try? Data(contentsOf: apiURL!)
let message = String(data: result!, encoding: String.Encoding.utf8)
DispatchQueue.main.async
{
self.label.text = message
}
}
}

3、总结

  • Thread(基于thread):每个Thread对象对应一个线程,优点是量级较轻,使用简单,缺点是需要开发者自行管理线程的生命周期、线程同步、加锁解锁、睡眠以及唤醒等操作。
  • Operation(基于queue):不需要关心线程的管理和线程同步的事情,可以把精力放在自己需要执行的业务逻辑上,缺点是只能实现它或者使用它定义好的子类。
  • Grand Central Dispatch(task):基于C语言的一种高效、强大的多核编辑解决方案,其在后端管理着一个线程池,它不仅仅决定代码块将在那个线程被执行,还可以根据可用的系统资源对这些线程进行管理。
开发者在多线程技术进行选择时,如果追求简便、安全,可以选择基于队列的Operation技术。如果需要处理大量并发数据,同时又追求应用程序的性能和效率,可以选择Grand Central Dispatch。


ios swift多线程的实现 Multithreading的更多相关文章

  1. iOS - Threads 多线程

    1.Threads 1.1 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开 QQ.Xcode,系统就会分别启动两个进程. ...

  2. 关于Xcode正确运行swift多线程

    想跳过废话直接看解决方案的可以点击这里直接跳转,我这人写博客喜欢瞎逼逼. 还有一些我看过的不错的多线程资料,在此给出链接,点击这里直接跳转查看. 近来为了做操作系统课程设计,不得不去学习了下多线程. ...

  3. iOS中多线程知识总结(一)

    这一段开发中一直在处理iOS多线程的问题,但是感觉知识太散了,所以就把iOS中多线程的知识点总结了一下. 1.基本概念 1)什么是进程?进程的特性是什么? 进程是指在系统中正在运行的一个应用程序.   ...

  4. iOS开发多线程篇—多线程简单介绍

    iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...

  5. iOS开发多线程篇—线程安全

    iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块 ...

  6. iOS开发——多线程篇——多线程介绍

    一.进程和线程1.什么是进程进程是指在系统中正在运行的一个应用程序每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开迅雷.Xcode,系统就会分别启动2个进程 通过“活动监 ...

  7. iOS 开发多线程篇—GCD的常见用法

    iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...

  8. iOS开发多线程篇—创建线程

    iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...

  9. iOS开发多线程篇—线程间的通信

    iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...

随机推荐

  1. Flask基础(02)-->搭建Flask项目虚拟环境

    什么是虚拟环境? 虚拟环境:其实就是一个文件夹,是python环境的复制 为什么要搭建虚拟环境? 因为一台计算机上可能要同时开发多个不同的项目,那么这些项目有可能用到同一个包的不同版本,如此一来,我们 ...

  2. .net core中使用Bumblebee架设微服务网关

    Bumblebee是款基于.net core开发开源的http服务网关,经过最近版本的完善在功能足以满足作为微服务网关的需要.在微服务网关功能中它提供了应用服务负载,故障迁移,安全控制,监控跟踪和日志 ...

  3. 除了Web和Node,JavaScript还能做什么

    前言 提起JavaScript,我们也许经常会想到的是,可以用来写Web页面嘛,又或者,会想起Node.js 这个服务端环境,搞前后端同构. 那么,除此之外, JavaScript还可以做什么?   ...

  4. python的__name__ == \'__main__\' 意义

    转自http://www.jb51.net/article/51892.htm 很多新手刚开始学习python的时候经常会看到python 中__name__ = \'__main__\' 这样的代码 ...

  5. vertical-align之见

    ertical-align   英文翻译为垂直对齐 ,常用来应用于table 表格中文字的垂直居中:脱离表格后不常用: 有朋友问起:故总结记之: 开局一张图,下来全靠编 这是一个简单的四线表格,小学时 ...

  6. Scala 多继承顺序

    Trait多继承顺序: 准则: 如果有超类,则先调用超类的函数. 如果混入的trait有父trait,它会按照继承层次先调用父trait的构造函数. 如果有多个父trait,则按顺序从左到右执行. 所 ...

  7. ELK 学习笔记之 elasticsearch Mget操作

    Mget操作: 查询多个文档: curl -XGET 'http://192.168.1.151:9200/_mget' -d '{"docs": [{"_index&q ...

  8. 计算机视觉(二)-opencv之createTrackbar()详解

    摘要: 我学习openCV3看的是<学习openCV3>这本书,很厚的一本,不知道是不是因为自己看的还不是很多,个人觉得里面的有些重要函数讲的不是很详细,比如createTrackbar( ...

  9. KafkaStream低级别API

    开发者可以通过Processor接口来实现自己的自定义处理逻辑.接口提供了Process和Punctuate方法. 其中:Process方法用于处理接受到的消息 Punctuate方法指定时间间隔周期 ...

  10. 网页布局——Flex弹性框布局

    布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 需要安卓4.4及以上版本可以使用 ...