多线程
卖票 与 多线程同步
创建并启动线程
let thread1 = Thread(target: self, selector: #selector(thread1Action), object: nil) // 创建一个线程对象
thread1.start() // 启动线程
方法2 创建并启动线程
Thread.detachNewThreadSelector(#selector(thread2Action), toTarget: self, with: nil)
多线程同步,及其的意义
// 为了线程同步 ,定义一些线程锁
var threadLock :NSLock!// 定义进程锁
线程锁
threadLock.lock() //上锁
//...
//线程工作内容
threadLock.unlock() //解锁
同步 例子
import UIKit
class ViewController: UIViewController {
var idTicket: Int = 200000 // 模拟票的总数,每张票的ID
var salerTicketCnt: Int! // 每个站点售票数量
var threadLock: NSLock! // 线程锁
override func viewDidLoad() {
super.viewDidLoad()
salerTicketCnt = idTicket / 2 // 每个站点售票数量
threadLock = NSLock() // 构造线程锁对象
// layout
let btn1 = UIButton(frame: CGRect(x: 20, y: 100, width: self.view.bounds.size.width - 40, height: 30))
btn1.addTarget(self, action: #selector(btn1Action), for: .touchDown)
btn1.setTitle("站点1开始售票", for: .normal)
btn1.layer.backgroundColor = UIColor.lightGray.cgColor
btn1.setTitleColor(UIColor.black, for: .normal)
self.view.addSubview(btn1)
let btn2 = UIButton(frame: CGRect(x: 20, y: 200, width: self.view.bounds.size.width - 40, height:30))
btn2.addTarget(self, action: #selector(btn2Action), for: .touchDown)
btn2.setTitle("站点2开始售票", for: .normal)
btn2.layer.backgroundColor = UIColor.lightGray.cgColor
btn2.setTitleColor(UIColor.black, for: .normal)
self.view.addSubview(btn2)
}
@objc func btn1Action() {
let thread1 = Thread(target: self, selector: #selector(thread1Action), object: nil) // 创建进行
thread1.start() // 启动进行
}
@objc func btn2Action() {
Thread.detachNewThreadSelector(#selector(thread2Action), toTarget: self, with: nil) // 创建并启动线程
}
@objc func thread1Action() { // 线程1目标方法
for _ in 0..<salerTicketCnt {
print("站点1:\(idTicket)") // 模拟售票
threadLock.lock() // 线程锁定
idTicket -= 1 // 模拟售票,ID自减
threadLock.unlock() // 线程解锁
}
}
@objc func thread2Action() { // 线程2目标方法
for _ in 0..<salerTicketCnt {
print("站点2:\(idTicket)") // 模拟售票
threadLock.lock() // 线程锁定
idTicket -= 1 // 模拟售票,ID自减
threadLock.unlock() // 线程解锁
}
}
}
console 情况
GCD
Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。
[百度百科]
- 使用时候不需要考虑线程池出入。
- 不需要思考线程管理,而只用care让线程干什么,GCD 会自动管理线程的生命周期(创建销毁线 程,调度任务)
- 自动使用多核并行。
先看一个异步的简单例子:
例子:MultiThreadTimer
//
// ViewController.swift
// MultiThreadDispatch
//
// Created XS on 2018/12/12.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var labelCount01: UILabel!
@IBOutlet weak var labelCount02: UILabel!
var isStop = false // 计时停止标记
@IBAction func btnStart01(_ sender: UIButton) {
isStop = false
let golbalQueue = DispatchQueue.global() // 获取GCD全局异步队列
golbalQueue.async { // 调用async方法,创建异步任务
for i in 1...10000 {
if (self.isStop) {
break
}
Thread.sleep(forTimeInterval: 0.001) // 线程休眠
// 主线程异步执行(主线程同步可能会死锁)
DispatchQueue.main.async(execute: { // 获取主线程队列,调用async方法
self.labelCount01.text = "\(i) ms"
})
}
}
}
@IBAction func btnStart02(_ sender: UIButton) {
isStop = false
DispatchQueue.global().async {
for i in 1...100000 {
if (self.isStop) {
break
}
Thread.sleep(forTimeInterval: 0.001)
DispatchQueue.main.async(execute: {
self.labelCount02.text = "\(i) ms"
})
}
}
}
@IBAction func btnStop(_ sender: UIButton) {
isStop = true
}
}
let golbalQueue = DispatchQueue.global() // 全局的GCD 的移步队列
// 创建异步任务
golbalQueue.async {
// job...
}