iOS线程池的创建和使用

2,559 阅读3分钟

创建和使用线程池可以通过 OperationQueueDispatchQueue 实现。这些工具可以帮助你管理多个并发任务,提高应用性能。

线程池的优点

  • 资源管理:限制最大并发数,防止过多线程导致资源竞争和性能问题。
  • 任务依赖:可以设置任务依赖关系,确保任务按顺序执行。
  • 任务重用:线程池可以重用线程,减少线程创建和销毁的开销。

线程池的具体应用

  1. 网络请求:在进行多个网络请求时,可以使用线程池来管理这些请求,避免阻塞主线程。
  2. 图像处理:处理大量图像时,可以使用线程池来分配多个线程并行处理,提高处理效率。
  3. 数据解析:解析大量数据时,可以将解析任务分配到多个线程中进行并行处理,加快解析速度。

使用 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 调度。