PriorityBlockingQueue 的核心构造方法源码

13 阅读2分钟
public PriorityBlockingQueue(Collection<? extends E> c) {
        //获取锁
        this.lock = new ReentrantLock();
        //队列未满的条件
        this.notEmpty = lock.newCondition();
        //heapify:如果为 true,则表示集合中的元素可能不在堆顺序中,需要进行堆化处理。
        boolean heapify = true; // true if not known to be in heap order
        //screen:如果为 true,则表示需要检查数组中的元素是否包含 null 值。
        boolean screen = true;  // true if must screen for nulls
        //如果是sortedSet,则获取比较器
        if (c instanceof SortedSet<?>) {
            SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
            this.comparator = (Comparator<? super E>) ss.comparator();
            //并设置heapify为false
            heapify = false;
        }
        //检查传入的集合是否是 PriorityBlockingQueue:如果是 PriorityBlockingQueue,则获取其比较器。
        //如果集合是 PriorityBlockingQueue 类型且没有自定义比较器,
        //则 heapify 也设置为 false,因为元素已经按优先级排序。
        else if (c instanceof PriorityBlockingQueue<?>) {
            PriorityBlockingQueue<? extends E> pq =
                (PriorityBlockingQueue<? extends E>) c;
            this.comparator = (Comparator<? super E>) pq.comparator();
            screen = false;
            if (pq.getClass() == PriorityBlockingQueue.class) // exact match
                heapify = false;
        }
        //使用 c.toArray() 方法将集合中的元素转换为数组。
        Object[] a = c.toArray();
        //获取数组长度
        int n = a.length;
        // If c.toArray incorrectly doesn't return Object[], copy it.
         //如果转换后的数组类型不是 Object[],
        if (a.getClass() != Object[].class)
            //则使用 Arrays.copyOf 方法创建一个新的 Object[] 类型的数组。
            a = Arrays.copyOf(a, n, Object[].class);
        if (screen && (n == 1 || this.comparator != null)) {
            for (int i = 0; i < n; ++i)
                if (a[i] == null)
                    throw new NullPointerException();
        }
        this.queue = a;
        this.size = n;
        //堆化处理:如果 heapify 为 true,则调用 heapify() 方法对数组进行堆化处理,以确保数组满足最大堆的性质。
        if (heapify)
            heapify();
    } 
//堆化处理的代码:

   private void heapify() {
        //获取当前队列的数组
        Object[] array = queue;
        //当前队列的size
        int n = size;
        //将 n 无符号右移1位,计算出最后一个非叶子节点的索引
        int half = (n >>> 1) - 1;
        //获取优先队列的比较强
        Comparator<? super E> cmp = comparator;
        //如果为Null,则未提供比较器
        if (cmp == null) {
            //从最后一个非叶子节点开始向上遍历至根节点。
            for (int i = half; i >= 0; i--)
                //调用 siftDownComparable 方法,将当前节点的元素向下“筛选”,确保父节点的优先级高于子节点。
                siftDownComparable(i, (E) array[i], array, n);
        }
        else {
            //同样从最后一个非叶子节点开始向上遍历。
            for (int i = half; i >= 0; i--)
                //调用 siftDownUsingComparator 方法,使用提供的 Comparator 来比较元素,并执行相同的向下筛选操作。
                siftDownUsingComparator(i, (E) array[i], array, n, cmp);
        }
    }

    siftDownComparable 和 siftDownUsingComparator 都是 PriorityBlockingQueue 类中的私有方法,
    它们实现了堆化过程中的向下筛选操作。在 siftDown 方法中,会检查当前节点的左右子节点,
    将当前节点与其子节点中优先级更高的节点进行交换,直到节点到达一个位置,使得其优先级高于其子节点或者成为叶子节点。