标签:vat lse tmp 导致 内存 pen isp init 问题
这里使用数组来存储栈的数据。不足之处在于本例中的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
}
}
标签:vat lse tmp 导致 内存 pen isp init 问题
原文地址:https://www.cnblogs.com/dev-walden/p/11396048.html