b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

链表 结构 解读 Java 并发队列 BlockingQueue(7)

电脑杂谈  发布时间:2018-02-21 23:42:01  来源:网络整理

我们可以假设出一个男女配对的场景:一个男的过来,如果一个人都没有,那么他需要等待;如果发现有一堆男的在等待,那么他需要排到队列后面;如果发现是一堆女的在排队,那么他直接牵走队头的那个女的。

既然这里说到了等待队列,我们先看看其实现,也就是 QNode:

static final class QNode {

volatile QNode next; // 可以看出来,等待队列是单向链表

volatile Object item; // CAS'ed to or from null

volatile Thread waiter; // 将线程对象保存在这里,用于挂起和唤醒

final boolean isData; // 用于判断是写线程节点(isData == true),还是读线程节点

QNode(Object item, boolean isData) {

this.item = item;

this.isData = isData;

}

......

相信说了这么多以后,我们再来看 transfer 方法的代码就轻松多了。

/**

* Puts or takes an item.

*/

Object transfer(Object e, boolean timed, long nanos) {

QNode s = null; // constructed/reused as needed

boolean isData = (e != null);

for (;;) {

QNode t = tail;

QNode h = head;

if (t == null || h == null) // saw uninitialized value

continue; // spin

// 队列空,或队列中节点类型和当前节点一致,

// 即我们说的第一种情况,将节点入队即可。读者要想着这块 if 里面方法其实就是入队

if (h == t || t.isData == isData) { // empty or same-mode

QNode tn = t.next;

// t != tail 说明刚刚有节点入队,continue 即可

if (t != tail) // inconsistent read

continue;

// 有其他节点入队,但是 tail 还是指向原来的,此时设置 tail 即可

if (tn != null) { // lagging tail

// 这个方法就是:如果 tail 此时为 t 的话,设置为 tn

advanceTail(t, tn);

continue;

}

//

if (timed && nanos <= 0) // can't wait

return null;

if (s == null)

s = new QNode(e, isData);

// 将当前节点,插入到 tail 的后面

if (!t.casNext(null, s)) // failed to link in

continue;

// 将当前节点设置为新的 tail

advanceTail(t, s); // swing tail and wait

// 看到这里,请读者先往下滑到这个方法,看完了以后再回来这里,思路也就不会断了

Object x = awaitFulfill(s, e, timed, nanos);

// 到这里,说明之前入队的线程被唤醒了,准备往下执行

if (x == s) { // wait was cancelled


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-87792-7.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...