创建和使用线程池可以通过 OperationQueue 和 DispatchQueue 实现。这些工具可以帮助你管理多个并发任务,提高应用性能。
线程池的优点
- 资源管理:限制最大并发数,防止过多线程导致资源竞争和性能问题。
- 任务依赖:可以设置任务依赖关系,确保任务按顺序执行。
- 任务重用:线程池可以重用线程,减少线程创建和销毁的开销。
线程池的具体应用
- 网络请求:在进行多个网络请求时,可以使用线程池来管理这些请求,避免阻塞主线程。
- 图像处理:处理大量图像时,可以使用线程池来分配多个线程并行处理,提高处理效率。
- 数据解析:解析大量数据时,可以将解析任务分配到多个线程中进行并行处理,加快解析速度。
使用 OperationQueue 实现线程池
OperationQueue 是一个高级的 API,用于管理和执行 Operation 对象。它提供了多线程的便利性,同时也允许对任务进行细粒度的控制。
import Foundation
// 创建一个OperationQueue
let operationQueue = OperationQueue()
// 设置最大并发操作数
operationQueue.maxConcurrentOperationCount = 5
// 创建操作
let operation1 = BlockOperation {
// 执行任务1
print("Task 1 executed")
}
let operation2 = BlockOperation {
// 执行任务2
print("Task 2 executed")
}
// 添加依赖,确保operation2在operation1完成后执行
operation2.addDependency(operation1)
// 将操作添加到队列中
operationQueue.addOperation(operation1)
operationQueue.addOperation(operation2)
使用 DispatchQueue 实现线程池
DispatchQueue 是一个低级别的 API,用于管理 GCD(Grand Central Dispatch)队列。它提供了全局并发队列和自定义串行/并发队列。
import Foundation
// 创建并发队列
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
// 提交任务到并发队列
concurrentQueue.async {
// 执行任务1
print("Task 1 executed")
}
concurrentQueue.async {
// 执行任务2
print("Task 2 executed")
}
封装
利用 OperationQueue 来实现一个线程池工具类。这个工具类将提供简单的接口以便外部调用,充分利用系统的 CPU 调度。
import Foundation
class ThreadPool {
// 单例模式
static let shared = ThreadPool()
// 创建一个OperationQueue
private let operationQueue: OperationQueue
// 私有初始化方法,防止外部实例化
private init() {
self.operationQueue = OperationQueue()
// 设置最大并发操作数,系统会根据设备资源自动调整
self.operationQueue.maxConcurrentOperationCount = OperationQueue.defaultMaxConcurrentOperationCount
}
// 添加任务到线程池
func addTask(_ task: @escaping () -> Void) {
let operation = BlockOperation(block: task)
operationQueue.addOperation(operation)
}
// 添加带依赖的任务到线程池
func addTask(_ task: @escaping () -> Void, dependencies: [Operation]) {
let operation = BlockOperation(block: task)
for dependency in dependencies {
operation.addDependency(dependency)
}
operationQueue.addOperation(operation)
}
// 取消所有任务
func cancelAllTasks() {
operationQueue.cancelAllOperations()
}
// 设置最大并发操作数
func setMaxConcurrentOperationCount(_ count: Int) {
operationQueue.maxConcurrentOperationCount = count
}
// 返回当前队列中的任务数
func currentTaskCount() -> Int {
return operationQueue.operationCount
}
}
// 使用示例
ThreadPool.shared.addTask {
print("Task 1 executed")
}
ThreadPool.shared.addTask {
print("Task 2 executed")
}
let task3 = BlockOperation {
print("Task 3 executed")
}
ThreadPool.shared.addTask({
print("Task 4 executed")
}, dependencies: [task3])
ThreadPool.shared.setMaxConcurrentOperationCount(4)
print("Current task count: \(ThreadPool.shared.currentTaskCount())")
// 取消所有任务
// ThreadPool.shared.cancelAllTasks()
代码说明
-
单例模式:
ThreadPool类采用单例模式,以确保全局只有一个线程池实例。 -
OperationQueue:创建了一个
OperationQueue用于管理任务。 -
添加任务:提供了
addTask方法,可以将任务添加到线程池中执行。 -
带依赖的任务:提供了
addTask方法,可以将带依赖的任务添加到线程池中执行。 -
取消任务:提供了
cancelAllTasks方法,可以取消所有正在执行和等待执行的任务。 -
设置最大并发操作数:提供了
setMaxConcurrentOperationCount方法,可以动态调整最大并发操作数。 -
获取当前任务数:提供了
currentTaskCount方法,可以获取当前队列中的任务数。
通过这个封装好的线程池工具类,外部可以直接调用接口来添加、管理和取消任务,并充分利用系统的 CPU 调度。