nslock
let queue = DispatchQueue(label: "Queue1", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
let queue2 = DispatchQueue(label: "queue2", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
let lock = NSLock()
var array = Array(0...10000)
func getLastItem() -> Int?{
lock.lock()
var temp: Int? = nil
let count = array.count
if count > 0{
temp = array[count - 1]
}
lock.unlock()
return temp
}
func removeLastItem(){
lock.lock()
array.removeLast()
lock.unlock()
}
queue.async {
for _ in 0 ..< 1000{
removeLastItem()
}
}
queue2.async {
for _ in 0..<1000{
print(getLastItem() ?? 0)
}
}
Lock wastes too much perfomance in the case of very few write opertions. Use Barrier instead.
Barrier will not execute until other threads finished executing
let queue = DispatchQueue(label: "Queue1", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
let queue2 = DispatchQueue(label: "queue2", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
let arrayQueue = DispatchQueue(label: "arrayQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
var array = Array(0...1000)
func getLastItem() -> Int?{
return arrayQueue.sync {
if array.count > 0 {
return array[array.count - 1]
}
return -1
}
}
func removeLastItem(){
let workItem = DispatchWorkItem(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
array.removeLast()
}
arrayQueue.async(execute: workItem)
}
queue.async {
for _ in 0 ..< 1000{
removeLastItem()
}
}
queue2.async {
for _ in 0..<1000{
print(getLastItem() ?? 0)
}
}