swift实现线程安全的栈和队列

Posted dev-walden

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift实现线程安全的栈和队列相关的知识,希望对你有一定的参考价值。

实现一个线程安全的栈

这里使用数组来存储栈的数据。不足之处在于本例中的Stack可以无限扩容,更好的是初始化时候指定一个最大容量,防止不断扩容申请内存导致内存不够的问题。这里的线程安全使用一个串行队列来保证,实际上也可以通过加锁或者信号量甚至自旋锁来解决。

struct Stack<Element> 
    
    private var items: [Element]
    
    private var queue = DispatchQueue(label: "StackOperationQueue")
    
    public init(capacity: Int = 10) 
        items = [Element]()
        items.reserveCapacity(capacity)
    
    
    mutating public func push(item: Element) 
        queue.sync 
            items.append(item)
        
    
    
    mutating public func pop() -> Element? 
        var item: Element?
        queue.sync 
            item = items.removeLast()
        
        return item
    

实现一个线程安全的队列

// 存储数据的双向链表节点
class DoubleLinkNode<Element> 
    var previous: DoubleLinkNode?
    var next: DoubleLinkNode?
    let val: Element?
    init(val: Element?) 
        self.val = val
    
    //声明==运算符,便于判断两个节点是否相等
    static func ==(left: DoubleLinkNode<Element>, right: DoubleLinkNode<Element>) -> Bool 
        //最准确的做法是判断内存地址是否相同
        let leftPointValue = Unmanaged<AnyObject>.passUnretained(left).toOpaque()
        let rightPointValue = Unmanaged<AnyObject>.passUnretained(right).toOpaque()
        return leftPointValue == rightPointValue
    


/*
 1.使用双向链表实现队列结构,声明空的head/last哨兵节点简化双向链表操作;
 2.使用串行队列保证线程安全,实际上也可以通过加锁的方式实现线程安全;
 3.对于生产者-消费者模型,这里可以使用semaphore来实现,当队列为空的时候,让线程休眠,当有元素入队的时候唤醒一个线程继续执行任务。
 */
struct Queue<Element> 
    //声明串行队列,将操作放在串行队列中,保证线程安全
    private var queue = DispatchQueue(label: "QueueOperationQueue")
    
    let firstNode: DoubleLinkNode<Element>
    let lastNode: DoubleLinkNode<Element>
    
    public init(capacity: Int = 20) 
        firstNode = DoubleLinkNode(val: nil)
        lastNode = DoubleLinkNode(val: nil)
        firstNode.next = lastNode
        lastNode.previous = firstNode
    
    
    /// 入队操作
    mutating public func enqueue(item: Element) 
        queue.sync 
            let node = DoubleLinkNode<Element>(val: item)
            let tmp = firstNode.next
            firstNode.next = node
            node.previous = firstNode
            node.next = tmp
            tmp?.previous = node
        
    
    
    /// 出队操作
    mutating public func dequeue() -> Element? 
        guard let previous = lastNode.previous, !(firstNode == previous) else  return nil 
        var node: DoubleLinkNode<Element>? = nil
        queue.sync 
            node = lastNode.previous
            node?.next = nil
            node?.previous = nil
            let tmp = node?.previous
            lastNode.previous = tmp
            tmp?.next = lastNode
        
        return node?.val
    

以上是关于swift实现线程安全的栈和队列的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 分派到主队列是不是足以使 var 线程安全?

C/C++线程安全型队列的实现

Java:基于LinkedList实现栈和队列

将 Swift 调用同步到基于 C 的线程不安全库

基于event 实现的线程安全的优先队列(python实现)

python端口扫描用多线程+线程安全的队列+Thread类实现