BlockingQueue---PriorityBlockingQueue

总结

  一个无界的并发队列。

  FIFO

  按照元素的优先级顺序来处理元素。这种队列非常适合需要按照优先级处理任务的场景。

特性

  • 无界:默认情况下是无界的,可以存储任意数量的元素。
  • 基于优先级:队列中的元素根据它们的自然顺序或者由构造时提供的 Comparator 来排序
  • 线程安全:支持多线程同时进行插入和移除操作。
  • 非阻塞插入操作不会被阻塞,即使队列中已经有很多元素;但是取元素的操作可能会被阻塞,如果队列为空。

构造函数

  • PriorityBlockingQueue(): 创建一个默认初始容量为11的 PriorityBlockingQueue
  • PriorityBlockingQueue(int initialCapacity): 创建一个具有指定初始容量的 PriorityBlockingQueue
  • PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator): 创建一个具有指定初始容量并使用指定比较器的 PriorityBlockingQueue
  • PriorityBlockingQueue(Collection<? extends E> c): 用给定集合中的元素初始化队列。
  • PriorityBlockingQueue(PriorityBlockingQueue<? extends E> c): 用另一个 PriorityBlockingQueue 初始化当前队列。
  • PriorityBlockingQueue(SortedSet<? extends E> c): 用给定有序集合中的元素初始化队列。

方法

  • 插入操作:

    • put(E e): 将指定的元素插入此优先级队列中。这个方法实际上等同于 offer(E e),因为 PriorityBlockingQueue 是无界的。
    • offer(E e): 将指定的元素插入此优先级队列中。由于队列是无界的,所以总是会成功添加元素。
  • 移除操作:

    • take(): 检索并移除此队列的头最高优先级),如果队列为空,则等待有元素可用。
    • poll(): 检索并移除此队列的头最高优先级),如果队列为空,则立即返回 null
    • poll(long timeout, TimeUnit unit): 检索并移除此队列的头(最高优先级),如果队列为空,则最多等待指定的时间,如果超时队列仍然为空则返回 null
  • 检查操作:

    • peek(): 检索但不移除此队列的头(最高优先级);如果队列为空,则返回 null

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public class PriorityBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {
        private static final int DEFAULT_INITIAL_CAPACITY = 11;
        private transient Object[] queue;
        private transient int size;
        private transient Comparator<? super E> comparator;
        private final ReentrantLock lock;
 
        public PriorityBlockingQueue() {
            this(DEFAULT_INITIAL_CAPACITY, null);
        }
 
        public PriorityBlockingQueue(int initialCapacity) {
            this(initialCapacity, null);
        }
 
        public PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator) {
            if (initialCapacity < 1)
                throw new IllegalArgumentException();
            this.lock = new ReentrantLock();
            this.notEmpty = lock.newCondition();
            this.comparator = comparator;
            this.queue = new Object[initialCapacity];
        }
 
        // 插入指定元素到优先级队列
        public boolean offer(E e) {
            if (e == null)
                throw new NullPointerException();
            final ReentrantLock lock = this.lock;
            lock.lock();
            int n, cap;
            Object[] array;
            while ((n = size) >= (cap = (array = queue).length))
                tryGrow(array, cap);
            try {
                Comparator<? super E> cmp = comparator;
                if (cmp == null)                                        //
                    siftUpComparable(n, e, array);
                else
                    siftUpUsingComparator(n, e, array, cmp);
                size = n + 1;
                notEmpty.signal();
            } finally {
                lock.unlock();
            }
            return true;
        }
 
        public E poll() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return dequeue();
            } finally {
                lock.unlock();
            }
        }
 
        private E dequeue() {
            int n = size - 1;
            if (n < 0)
                return null;
            else {
                Object[] array = queue;
                E result = (E) array[0];
                E x = (E) array[n];
                array[n] = null;
                Comparator<? super E> cmp = comparator;
                if (cmp == null)
                    siftDownComparable(0, x, array, n);
                else
                    siftDownUsingComparator(0, x, array, n, cmp);
                size = n;
                return result;
            }
        }
    }

  

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public static void main(String[] args) throws InterruptedException {
 
        // 创建一个PriorityBlockingQueue,使用自定义的降序比较器
        PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>(10, (a, b) -> b - a); // 降序
 
        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i);
                    System.out.println("Produced: " + i);
                }
            } catch (Exception e) {
                Thread.currentThread().interrupt();
            }
        });
 
        producer.start();
 
        Thread.sleep(1000);
 
        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    Integer element = queue.take();
                    System.out.println("Consumed: " + element);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
 
 
        consumer.start();
         
        // 结果:
        // Produced: 0
        //Produced: 1
        //Produced: 2
        //Produced: 3
        //Produced: 4
        //Produced: 5
        //Produced: 6
        //Produced: 7
        //Produced: 8
        //Produced: 9
        //Consumed: 9
        //Consumed: 8
        //Consumed: 7
        //Consumed: 6
        //Consumed: 5
        //Consumed: 4
        //Consumed: 3
        //Consumed: 2
        //Consumed: 1
        //Consumed: 0
    }

  

posted on   anpeiyong  阅读(10)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示