ダム自身、常にその横に仕上げ、周りのビットを感じて〜
private Node enq(final Node node) {
//自旋锁
for (;;) {
//tail默认就是null
Node t = tail;
if (t == null) { // Must initialize
//因为tail默认是null,所以首次一定会进来
//compareAndSetHead在下面
//也就是首次一定会把一个新的node设置为head
if (compareAndSetHead(new Node()))
//tail=head=new Node()
tail = head;
//到这里就是tail和head都会指向new Node
} else {
//第二次一定进入else发
//假如此时进入了一个线程A,这个A已经被封装成了node传进来
//当前的node的pre指向t,也就是tail,也就是刚才创建的Node,
//因为第一行就定义了Node t = tail,而t=head=node
node.prev = t;
//这里看下面的compareAndSetTail方法
//把tail节点赋值为新传入的node(Thread A),赋值操作就相当于指向
if (compareAndSetTail(t, node)) {
//这里的t指的是原来的tail节点,tail指向一开始的new Node
//所以就是new Node的next指向新传入的node(Thread A)
t.next = node;
return t;
}
}
}
}
private final boolean compareAndSetHead(Node update) {
//当前的head字段,和null值比对,默认是null,所以相等,所以赋值为update,也就是new node()
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}
private final boolean compareAndSetTail(Node expect, Node update) {
//当前的tail字段和期望值exepct,即t进行比较,一定是相等的啊,以为t=tail么,所以更新赋值为update,
//即新传进来的node(Thread A)
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}
最初の場合は入力する必要があります
新しいスレッドが(実際には、新しいスレッドが入っていないか、他の人のに入ろうとして)他の入力時に入力するようにすると、赤は動作が他のやっています
要約:
頭と尾がノードであるが、ここで私は次もPREVとを含む、この双方向リンクリスト、ない実用的な意義を、ポインタのようなもの、その存在の意味として理解だけでなく、維持すること。
主なアイデアはあるにかなりの周り、私は完全に理解する必要性を全く感じません
最初の新しいノードが戻って新しいノードを追加するには、リストの先頭に時間、2ウェイバックを渡し、ノードの二重リンクリストを作成するために、空気中に来て、頭と尾は常にポイント最初と最後に、真ん中のいくつかでありますスイッチングポインタ(I代入ような割り当て尾と頭の割り当てなどのオペレータ、PREVと隣接して、それへのポインタ、と理解される時間のためにここにいます。)
用(;;)ノードを追加しようとするノンストップ、スピン・ロックですが、そこに、そのCASの方法により、並行性の問題も追加し、イニシアチブ、彼はまだ起こっているこの時間をつかむために、スレッドの最後の時間がかかるかもしれないこと、どのようにしようとして維持しようと?だから、スピンロックを通じて解決、もちろん、あなたが追加した場合、最終的な結果は、リターンでスピンロックをポップアップ表示されます。
個人的に私は非常に強力で、このカススピンロックと操作は、それは価値が学習であると思います!
また、あなたは速やかに指摘したい問題がある場合は、上記のすべては、私の個人的な理解で、大きな問題がある可能性があり、私は、あなたを誤解しないように願っています。