站在使用者的角度,future是一个经常在多线程环境下使用的Runnable,使用它的好处有两个:


红色标记的地方表示,当当前线程池的大小小于corePoolSize时,将任务提交,否则将该任务加入到workQueue中去,如果workQueue装满了,则尝试在线程数小于MaxPoolSize的条件下提交该任务。




private void doReleaseShared() {
/*
* Ensure that a release propagates, even if there are other
* in-progress acquires/releases. This proceeds in the usual
* way of trying to unparkSuccessor of head if it needs
* signal. But if it does not, status is set to PROPAGATE to
* ensure that upon release, propagation continues.
* Additionally, we must loop in case a new node is added
* while we are doing this. Also, unlike other uses of
* unparkSuccessor, we need to know if CAS to reset status
* fails, if so rechecking.
*/
for (;;) {
Node h = head;//把头元素取出来,保持头元素的引用,防止head被更改
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {//如果状态位为:需要一个信号去唤醒 注释原话:/** waitStatus value to indicate successor's thread needs unparking */
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) //修改状态位
continue; // loop to recheck cases
unparkSuccessor(h);//如果修改成功,则通过头元素找到一个线程,并且唤醒它(唤醒动作是通过JNI方法去调用的)
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}

private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
throws InterruptedException {
long lastTime = System.nanoTime();
final Node node = addWaiter(Node.SHARED);//在队列尾部增加一个结点,我的理解是,用来标明这个队列是共享者队列还是独占队列
try {
for (;;) {
final Node p = node.predecessor();//拿出刚才新增结点的前一个结点:实际有效的队尾结点。
if (p == head) {
int r = tryAcquireShared(arg);//尝试获取锁。
if (r >= 0) {//
setHeadAndPropagate(node, r);//返回值大于1 对于FutureTask代表任务已经被cancel了,则更改队列头部结点。
p.next = null; // help GC 将p结点脱离队列,帮助GC
return true;//返回true后 上述中可以知道当前线成会抛出超时异常 确定下会不会唤醒其他节点?
}
}
if (nanosTimeout <= 0) { //如果设置的超时时间小于等于0 则取消获取锁
cancelAcquire(node);
return false;
}
if (nanosTimeout > spinForTimeoutThreshold && //等待的时间必须大于一个自旋锁的周期时间
shouldParkAfterFailedAcquire(p, node)) // 遍历队列,找到需要沉睡的第一个节点
LockSupport.parkNanos(this, nanosTimeout); // 调用JNI方法,沉睡当前线程
long now = System.nanoTime();
nanosTimeout -= now - lastTime; // 更新等待时间 循环遍历
lastTime = now;
if (Thread.interrupted())
break;
}
} catch (RuntimeException ex) {
cancelAcquire(node);
throw ex;
}
// Arrive here only if interrupted
cancelAcquire(node);
throw new InterruptedException();
}
2484



被折叠的 条评论
为什么被折叠?



