Java基础 - 13 Queue之DelayQueue、PriorityQueue、PriorityBlockingQueue讲解
在Java的队列世界里,有三位大佬,他们分别是DelayQueue、PriorityQueue和PriorityBlockingQueue。今天,让我们一起揭开他们神秘的面纱,看看他们各自的特点和用途吧!
DelayQueue
首先,让我们来认识一下DelayQueue。这位大佬有点“慢热”,因为他专门负责处理延迟任务。你可以把他想象成一个“倒计时专家”,只有在指定的延迟时间过后,任务才能被取出来。这在一些需要延迟执行的场景中非常有用,比如定时任务调度、缓存失效等。要使用DelayQueue,你需要实现Delayed接口,并重写getDelay()和compareTo()方法,让任务按照你的设定来执行。
DelayQueue 是 Java 中的一个并发工具类,用于存储实现了 Delayed 接口的元素,并且这些元素会在一定时间之后才能被获取。常用于实现定时任务调度、消息延迟处理等场景。
在 DelayQueue 中,常用的方法包括:
put(E e):将指定元素放入队列中。
take():获取并移除队列的头部元素,如果队列为空,则阻塞等待。
poll():获取并移除队列的头部元素,如果队列为空,则返回 null。
offer(E e):将指定元素插入队列中,如果成功则返回 true,否则返回 false。
下面是一个简单的示例代码,演示了如何使用 DelayQueue:
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
class DelayedElement implements Delayed {
private String data;
private long delayTime;
public DelayedElement(String data, long delayTime) {
this.data = data;
this.delayTime = System.currentTimeMillis() + delayTime;
}
@Override
public long getDelay(TimeUnit unit) {
long diff = delayTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(this.delayTime, ((DelayedElement) o).delayTime);
}
@Override
public String toString() {
return data;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();
delayQueue.put(new DelayedElement("Element 1", 2000));
delayQueue.put(new DelayedElement("Element 2", 5000));
System.out.println("Elements added to queue");
System.out.println(delayQueue.take());
System.out.println(delayQueue.take());
}
}
PriorityQueue
接下来,让我们迎接PriorityQueue,这位大佬可是“优先级之王”!他会根据元素的优先级来决定谁先出场,谁后登场。如果你有一堆任务,但又想要按照优先级来处理它们,PriorityQueue就是你的不二选择。你可以通过实现Comparable接口或者在构造函数中传入Comparator来定义元素的优先级顺序。这位大佬可是个“绅士”,总是把优先级最高的任务放在队列的最前面。
PriorityQueue 的特点和常用方法包括:
- 默认情况下是一个小顶堆,也可以通过自定义 Comparator 来实现大顶堆。
- 元素根据其自然顺序或者 Comparator 排序。
- 插入操作和删除操作的时间复杂度为 O(log n)。
- 不支持 null 元素。
常用方法包括:
- add(E e) / offer(E e):将元素插入队列。
- remove() / poll():获取并移除队列的头部元素。
- peek():获取但不移除队列的头部元素。
- size():返回队列的大小。
其他方法:
案例:
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) {
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.offer(3);
priorityQueue.offer(1);
priorityQueue.offer(2);
System.out.println("Elements in priority queue:");
while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.poll());
}
}
}
PriorityBlockingQueue
最后,让我们见识一下PriorityBlockingQueue,他是PriorityQueue的“大哥”,更加强大且安全。和PriorityQueue一样,他也是按照优先级来排序任务,但是在多线程环境下,PriorityBlockingQueue更加稳定可靠。他内部使用了可重入锁来保证线程安全,让你在多线程场景下也能够放心使用。如果你需要在多线程环境下处理优先级任务,PriorityBlockingQueue会是你的得力助手。
PriorityBlockingQueue 的特点和常用方法类似于 PriorityQueue,但是它是一个阻塞队列,支持生产者-消费者模型,具有以下特点:
- 是一个无界队列,可以存储任意数量的元素。
- 内部使用 ReentrantLock 来保证线程安全。
- 支持自定义 Comparator 来定义元素的优先级。
常用方法包括:
- put(E e):将元素插入队列,如果队列已满则阻塞等待。
- take():获取并移除队列的头部元素,如果队列为空则阻塞等待。
- offer(E e):将元素插入队列,如果成功则返回 true,否则返回 false。
- poll():获取并移除队列的头部元素,如果队列为空则返回 null。
其他方法:
案例:
import java.util.concurrent.PriorityBlockingQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<Integer> priorityBlockingQueue = new PriorityBlockingQueue<>();
priorityBlockingQueue.put(3);
priorityBlockingQueue.put(1);
priorityBlockingQueue.put(2);
System.out.println("Elements in priority blocking queue:");
while (!priorityBlockingQueue.isEmpty()) {
System.out.println(priorityBlockingQueue.take());
}
}
}
无论是“倒计时专家”DelayQueue、“优先级之王”PriorityQueue,还是“大哥”PriorityBlockingQueue,它们都各司其职,在Java队列的世界里发挥着重要作用。
原文地址:https://blog.csdn.net/qq_45922256/article/details/136257826
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!