ArrayBlockingQueue阻塞队列解析

小舟从此逝,江海寄余生。

先看构造方法

java.util.concurrent.ArrayBlockingQueue#ArrayBlockingQueue(int)
java.util.concurrent.ArrayBlockingQueue#ArrayBlockingQueue(int, boolean)

public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair); // 默认使用非公平锁
    // 不为空和未满分别对应一个条件队列
    notEmpty = lock.newCondition();
    notFull =  lock.newCondition();
}

调用put方法

java.util.concurrent.ArrayBlockingQueue#put

public void put(E e) throws InterruptedException {
    checkNotNull(e);
    final ReentrantLock lock = this.lock;
    // 先拿到锁
    lock.lockInterruptibly();
    try {
    	// 如果队列已满,notFull阻塞等待其他线程消费
        while (count == items.length)
            notFull.await();
        // 进行入队
        enqueue(e);
    } finally {
        lock.unlock();
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject#await()

public final void await() throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    // 新建节点加入条件队列
    Node node = addConditionWaiter();
    // 将锁释放
    int savedState = fullyRelease(node);
    int interruptMode = 0;
    // 判断节点是否在同步队列中,如果不在
    while (!isOnSyncQueue(node)) {
    	// 线程阻塞
        LockSupport.park(this);
        // 后面解析这个方法的作用,主要判断是否到同步队列中了
        if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
            break;
    }
    // 尝试获取锁,这个方法在共享锁里有讲
    if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
        interruptMode = REINTERRUPT;
    if (node.nextWaiter != null) // 如果条件队列中还有其他节点,剔除无效节点
        unlinkCancelledWaiters();
    if (interruptMode != 0)
        reportInterruptAfterWait(interruptMode);
}

java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject#addConditionWaiter

private Node addConditionWaiter() {
    Node t = lastWaiter;
    // 尾节点不为空,且状态不为Condition,则认为是死节点,进行清除尾部死节点
    if (t != null && t.waitStatus != Node.CONDITION) {
        unlinkCancelledWaiters();
        t = lastWaiter;
    }
    // 新建一个节点加入队列
    Node node = new Node(Thread.currentThread(), Node.CONDITION);
    if (t == null)
        firstWaiter = node;
    else
        t.nextWaiter = node;
    lastWaiter = node;
    return node;
}

java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject#unlinkCancelledWaiters
// 循环进行尾部死节点的清除
private void unlinkCancelledWaiters() {
    Node t = firstWaiter;
    Node trail = null;
    while (t != null) {
        Node next = t.nextWaiter;
        if (t.waitStatus != Node.CONDITION) {
            t.nextWaiter = null;
            if (trail == null)
                firstWaiter = next;
            else
                trail.nextWaiter = next;
            if (next == null)
                lastWaiter = trail;
        }
        else
            trail = t;
        t = next;
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#fullyRelease
// 把持有锁的次数全部释放
final int fullyRelease(Node node) {
    boolean failed = true;
    try {
        int savedState = getState();
        if (release(savedState)) {
            failed = false;
            return savedState;
        } else {
            throw new IllegalMonitorStateException();
        }
    } finally {
        if (failed)
            node.waitStatus = Node.CANCELLED;
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#isOnSyncQueue

final boolean isOnSyncQueue(Node node) {
	// 如果是条件队列,状态肯定不是condition,而且是有前驱指针的
    if (node.waitStatus == Node.CONDITION || node.prev == null)
        return false;
    // 如果后继指针不为空,即在同步队列中
    if (node.next != null)
        return true;
    // 都不满足的话从同步队列尾节点向前找,是否跟node指针相同
    return findNodeFromTail(node);
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#findNodeFromTail
// 从同步队列尾节点向前找,是否跟node指针相同
private boolean findNodeFromTail(Node node) {
    Node t = tail;
    for (;;) {
        if (t == node)
            return true;
        if (t == null)
            return false;
        t = t.prev;
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject#checkInterruptWhileWaiting
// 如果现在不是中断的,正常被signal唤醒返回0
// 如果节点由中断加入同步队列则返回THROW_IE,由signal加入同步队列则返回REINTERRUpt
private int checkInterruptWhileWaiting(Node node) {
    return Thread.interrupted() ?
        (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
        0;
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#transferAfterCancelledWait

final boolean transferAfterCancelledWait(Node node) {
	// 如果是Condition状态,修改为0,并入队同步队列
    if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
        enq(node);
        return true;
    }
    while (!isOnSyncQueue(node))
        Thread.yield();
    return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值