LinkedBlockingQueue 节点的 next 不可变
LinkedBlockingQueue node's next is not volatile
我正在阅读 LinkedBlockingQueue 代码,但我有一个问题,也许很简单,但我找不到答案,真的需要帮助。
我注意到 Node.next 不是易变的,像这样:
static class Node<E> {
E item;
LinkedBlockingQueue.Node<E> next;
Node(E var1) {
this.item = var1;
}
}
那么,新节点的入队(Node.next)如何通过另一个线程对出队可见?
private void enqueue(Node<E> node) {
// assert putLock.isHeldByCurrentThread();
// assert last.next == null;
last = last.next = node;
}
private E dequeue() {
// assert takeLock.isHeldByCurrentThread();
// assert head.item == null;
Node<E> h = head;
Node<E> first = h.next;
h.next = h; // help GC
head = first;
E x = first.item;
first.item = null;
return x;
}
方法 enqueue()
和 dequeue()
是私有的,因此只能从同一 class 中的其他方法调用,例如 peek()
、poll()
, put()
, offer()
, 等等
锁定在更高级别强制执行,并且两个线程永远不可能在竞争条件下同时访问节点的实例变量。
我正在阅读 LinkedBlockingQueue 代码,但我有一个问题,也许很简单,但我找不到答案,真的需要帮助。
我注意到 Node.next 不是易变的,像这样:
static class Node<E> {
E item;
LinkedBlockingQueue.Node<E> next;
Node(E var1) {
this.item = var1;
}
}
那么,新节点的入队(Node.next)如何通过另一个线程对出队可见?
private void enqueue(Node<E> node) {
// assert putLock.isHeldByCurrentThread();
// assert last.next == null;
last = last.next = node;
}
private E dequeue() {
// assert takeLock.isHeldByCurrentThread();
// assert head.item == null;
Node<E> h = head;
Node<E> first = h.next;
h.next = h; // help GC
head = first;
E x = first.item;
first.item = null;
return x;
}
方法 enqueue()
和 dequeue()
是私有的,因此只能从同一 class 中的其他方法调用,例如 peek()
、poll()
, put()
, offer()
, 等等
锁定在更高级别强制执行,并且两个线程永远不可能在竞争条件下同时访问节点的实例变量。