「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
💡 get方法
get方法是获取结果,如果当前任务仍然在执行中,那么将阻塞到获取结果
当状态为≤COMPLETING,说明线程当前正在运行中没有被取消,那么执行awaitDone方法阻塞等待.
report方法是收尾工作,返回结果.
1 | ini复制代码public V get() throws InterruptedException, ExecutionException { |
💡 awaitDone方法
该方法是实现阻塞的关键方法
1.查看入参是否设置了超时时间timed = true.来是否设置超时时间
2.自旋for(;;)
1.先判断当前线程是否中断,抛出异常,移除在等待队列中的等待节点
2.判断当前状态,如果大于COMPLETING,说明任务已经结束.线程置空并返回结果
3.如果还在执行state==COMPLETING,说明*当前任务已经执行结束,但是任务执行线程还没来得及给outcome赋值.*挂起线程,让其他任务执行线程优先执行.
4.等待节点为空,说明任务尚未执行,那么初始化一个等待节点.
5.如果没有入队列!queued,那么放到队列的头结点(由于是else if,因此创建等待节点时不会入队列)
5.如果设置了超时时间,计算当前还有多少时间超时t,如果超时t<0,删除对应节点并返回当前状态.阻塞t时间
6.阻塞等待直到被其他线程唤醒.(当任务线程执行结束,就会唤醒等待线程finishCompletion
)
1 | ini复制代码private int awaitDone(Boolean timed, long nanos) |
触发流程:
1.第一轮for循环,执行逻辑q == null,新建等待节点q,循环结束
2.第二轮for循环,执行!q,入队,循环结束.
3.第三轮for循环,进行阻塞等待或者阻塞特定时间,直到阻塞被其他线程唤醒.
4.唤醒后第四轮for循环,根据前三个条件进入对应的逻辑中
💡 finishCompletion
该方法主要用于唤醒线程.当任务结束或者异常时,会调用该方法
被唤醒的线程就会从awaitDown方法中的LockSupport的park或者parkNanos方法处唤醒,然后继续执行awaitDown方法
1 | ini复制代码private void finishCompletion() { |
本文转载自: 掘金