所以我正在阅读Maged M. Michael和Michael L. Scott撰写的文章Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms,还有一个我无法得到的小问题:
假设我们有两个并发线程在队列初始化后立即触发。其中一个线程调用enqueue
,另一个调用dequeue
。是什么阻止他们同时访问虚拟节点的next
字段?在dequeue
线程写入next
线程时,enqueue
线程是否可以读取{{1}}字段?他们都使用不同的锁...所以我不明白他们之间的同步..
感谢。
答案 0 :(得分:2)
enqueue()只操纵尾部,而dequeue()只操纵头部,因此它们不需要使用相同的锁。当head和tail指向同一节点时,有一种特殊情况,即在初始化时创建的“虚拟”节点。并且你是正确的,enqueue()可能正在写入该节点的下一个指针,而dequeue()正试图读取它。
并发读写没有问题。请注意,enqueue()创建一个新节点,并在通过将其写入tail-> next使其可见之前完全初始化该对象。因此,没有其他代码能够在中途初始化状态下看到这个新节点。此外,对指针的读/写是原子的,因此dequeue()不可能获得指针的一半。
所以在你的场景中,enqueue()和dequeue()都被立即调用,有两种可能性: