5.DelayedWorkQueue类#grow方法
private void grow() {int oldCapacity = queue.length;int newCapacity = oldCapacity + (oldCapacity >> 1); //新容量为原来的1.5倍if (newCapacity < 0) // overflownewCapacity = Integer.MAX_VALUE;queue = Arrays.copyOf(queue, newCapacity); //从旧数组 复制到 新数组}6.DelayedWorkQueue类#remove方法
public boolean remove(Object x) {final ReentrantLock lock = this.lock;lock.lock(); //加锁try {int i = indexOf(x); //定位xif (i < 0) //节点元素不存在return false;setIndex(queue[i], -1);int s = --size;//末节点作为替代节点RunnableScheduledFuture<?> replacement = queue[s];queue[s] = null;//原本末节点处置空,便于GCif (s != i) {//下移,保证该节点的子孙节点保持特性siftDown(i, replacement);// queue[i] == replacement说明下移没有发生if (queue[i] == replacement)//上移,保证该节点的祖先节点保持特性siftUp(i, replacement);}return true;} finally {lock.unlock(); //加锁}}7.DelayedWorkQueue类#siftDown方法
//情况说明:一般发生在队列头结点任务被取出了;这时候头结点空闲,会把队列【可看做是数组的情况会更好理解】末尾的元素【看作是树的话,上层数据要比下层的要小】放入头结点,然后向下转移,达到保持优先队列的情况 。private void siftDown(int k, RunnableScheduledFuture<?> key) {int half = size >>> 1;while (k < half) {int child = (k << 1) + 1; //左子节点坐标RunnableScheduledFuture<?> c = queue[child]; //c表示左右子节点中的较小者,暂时是左int right = child + 1; //右子节点坐标//两者进行比较,且下标没有超出数据个数if (right < size && c.compareTo(queue[right]) > 0)c = queue[child = right]; //右节点更小的话要变更数据和记录下标//直至找到下层没有比自身小的元素时就停下if (key.compareTo(c) <= 0)break;queue[k] = c;setIndex(c, k);k = child;}queue[k] = key;setIndex(key, k);}8.DelayedWorkQueue类#finishPoll方法
// f是队列头节点(!!!)private RunnableScheduledFuture<?> finishPoll(RunnableScheduledFuture<?> f) {int s = --size;RunnableScheduledFuture<?> x = queue[s];//取出队列尾节点的值(之后放到合适位置)queue[s] = null;//置空,便于GC// 尾节点从0开始向下遍历调整顺序if (s != 0)siftDown(0, x);setIndex(f, -1); //设置f的heapIndex属性return f;}1244574199069500L【补充部分---ScheduledThreadPoolExecutor类分析 线程池底层原理详解与源码分析】
经验总结扩展阅读
- 祖国像什么将句子补充完整
- 江苏属于几线城市
- rtk有哪三部分组成
- 高铁票怎么变成凭证了
- 博美狗狗剪毛教程
- 猪肉煮熟后部分发黑
- 苹果手机怎么复制截屏(苹果手机咋部分截屏)
- 房屋公摊面积包括哪些部分
- 我国企业现金流量表补充资料的内容有哪些?
- 企业资产包括哪两个部分?
