自定义RunLoop机制的线程池

98 阅读4分钟

实现一个类似于Objective-C RunLoop的线程池,能够处理不同优先级的任务,并且在运行过程中可以动态添加任务,在Swift中可以使用DispatchQueueOperationQueue来管理任务的并发执行。以下是一个示例实现,它模拟了一个具有不同优先级的线程池。该线程池使用OperationQueue来管理任务的执行,并提供高、中、低三个优先级的队列。用一个定时器,用于实时监测是否有新任务进来。同时,每次任务执行完成后,我们需要检查是否有更高级别的任务,如果有,则优先执行更高级别的任务,通过OperationQueuecompletionBlock属性来处理任务完成后的操作。在每个任务完成后,我们需要确保该任务从对应的优先级队列中移除,并继续检查是否有新的任务需要执行

以下是实现代码:

import Foundation

/// 任务优先级枚举
enum TaskPriority: Int {
    case low = 0
    case medium
    case high
}

/// 任务类,包含任务的优先级和任务本身的执行函数
class Task {
    let priority: TaskPriority
    let task: () -> Void
    
    init(priority: TaskPriority, task: @escaping () -> Void) {
        self.priority = priority
        self.task = task
    }
}

/// 线程池类,管理并发任务的执行
class ThreadPool {
    private let maxConcurrency: Int // 最大并发任务数
    private let queue: OperationQueue // 操作队列,用于管理任务的执行
    private let highPriorityQueue = OperationQueue() // 高优先级任务队列
    private let mediumPriorityQueue = OperationQueue() // 中优先级任务队列
    private let lowPriorityQueue = OperationQueue() // 低优先级任务队列
    private var timer: Timer? // 定时器,用于实时监测是否有新任务进来
    
    init(maxConcurrency: Int) {
        self.maxConcurrency = maxConcurrency
        self.queue = OperationQueue()
        self.queue.maxConcurrentOperationCount = maxConcurrency
        
        // 设置优先级队列的最大并发任务数
        highPriorityQueue.maxConcurrentOperationCount = maxConcurrency
        mediumPriorityQueue.maxConcurrentOperationCount = maxConcurrency
        lowPriorityQueue.maxConcurrentOperationCount = maxConcurrency
        
        // 启动定时器,实时监测是否有新任务进来
        startMonitoring()
    }
    
    /// 启动定时器,实时监测是否有新任务进来
    private func startMonitoring() {
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
            self?.executeNextTask()
        }
    }
    
    /// 添加任务到相应的优先级队列中,并尝试执行任务
    func addTask(_ task: Task) {
        let operation = BlockOperation(block: task.task)
        
        // 设置任务完成后的回调
        operation.completionBlock = { [weak self] in
            self?.taskDidComplete(task)
        }
        
        switch task.priority {
        case .high:
            highPriorityQueue.addOperation(operation)
        case .medium:
            mediumPriorityQueue.addOperation(operation)
        case .low:
            lowPriorityQueue.addOperation(operation)
        }
        
        // 尝试执行下一个任务
        executeNextTask()
    }
    
    /// 在任务完成后从对应的队列中删除任务,并尝试执行下一个任务
    private func taskDidComplete(_ task: Task) {
        // 使用主队列来确保线程安全
        DispatchQueue.main.async { [weak self] in
            self?.executeNextTask()
        }
    }
    
    /// 按照优先级顺序选择并尝试执行下一个任务
    private func executeNextTask() {
        if queue.operationCount >= maxConcurrency {
            return // 如果活动任务数达到最大并发数,则返回
        }
        
        if let highPriorityTask = highPriorityQueue.operations.first {
            queue.addOperation(highPriorityTask)
        } else if let mediumPriorityTask = mediumPriorityQueue.operations.first {
            queue.addOperation(mediumPriorityTask)
        } else if let lowPriorityTask = lowPriorityQueue.operations.first {
            queue.addOperation(lowPriorityTask)
        }
    }
    
    /// 清理所有任务
    func dispose() {
        timer?.invalidate()
        queue.cancelAllOperations()
        highPriorityQueue.cancelAllOperations()
        mediumPriorityQueue.cancelAllOperations()
        lowPriorityQueue.cancelAllOperations()
    }
}

// 使用示例
let threadPool = ThreadPool(maxConcurrency: 3)

// 添加低优先级任务
threadPool.addTask(Task(priority: .low) {
    print("Low priority task executed")
})

// 添加高优先级任务
threadPool.addTask(Task(priority: .high) {
    print("High priority task executed")
})

// 添加中优先级任务
threadPool.addTask(Task(priority: .medium) {
    print("Medium priority task executed")
})

// 添加另一个低优先级任务
threadPool.addTask(Task(priority: .low) {
    print("Another low priority task executed")
})

// 延迟5秒后清理线程池
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
    threadPool.dispose()
    print("Thread pool disposed")
}

详细注释说明

  • TaskPriority 枚举:定义了任务的优先级,分别为低(low)、中(medium)和高(high)。

  • Task 类:表示一个任务,包含任务的优先级和任务本身的执行函数。

  • ThreadPool 类:管理并发任务的执行。

    • maxConcurrency:最大并发任务数。
    • queue:操作队列,用于管理任务的执行。
    • highPriorityQueuemediumPriorityQueuelowPriorityQueue:分别存储不同优先级的任务队列,并设置它们的最大并发任务数。
    • timer:定时器,用于实时监测是否有新任务进来。
    • startMonitoring 方法:启动定时器,实时监测是否有新任务进来。
    • addTask 方法:将任务添加到相应的优先级队列中,并设置任务完成后的回调,然后尝试执行任务。
    • taskDidComplete 方法:在任务完成后从对应的队列中删除任务,并尝试执行下一个任务。
    • executeNextTask 方法:按照优先级顺序选择并尝试执行下一个任务。如果当前活动任务数小于最大并发数,则执行任务。
    • dispose 方法:清理所有任务,取消所有队列中的操作,并停止定时器。
  • 使用示例:创建一个线程池,并添加多个不同优先级的任务,最后延迟5秒后清理线程池。

通过这种方式,你可以在Swift中实现一个多线程的任务池,能够按优先级处理任务,并动态添加任务。同时,线程池会实时监测是否有新任务进来,并在每次任务执行完成后检查是否有更高级别的任务,如果有,则优先执行更高级别的任务。