java常用队列

780 阅读3分钟

在 Java 中,队列(Queue)是一个常用的数据结构,用于按特定顺序(通常是先入先出,FIFO)处理元素。Java 提供了多个实现,可以适用于不同的场景和需求。以下是 Java 常用的队列及其使用场景和用法:


1. LinkedList

使用场景:

  • 双端队列(Deque) :可以作为队列(FIFO)或栈(LIFO)使用。
  • 通用队列:适用于需要基本队列功能的小型场景。

用法:

Queue<Integer> queue = new LinkedList<>();
queue.offer(1); // 添加元素
queue.offer(2);
System.out.println(queue.poll()); // 移除并返回队首元素,输出1
System.out.println(queue.peek()); // 查看队首元素,不移除,输出2

2. PriorityQueue

使用场景:

  • 优先级队列:按元素的自然顺序(或提供的比较器顺序)排序。
  • 任务调度:处理需要优先级的任务,例如任务队列或事件管理。

用法:

Queue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.offer(3);
priorityQueue.offer(1);
priorityQueue.offer(2);
System.out.println(priorityQueue.poll()); // 输出1(按升序)

3. ArrayDeque

使用场景:

  • 高效的双端队列:比 LinkedList 更高效,适用于栈或队列的实现。
  • 替代栈:比 Stack 类更推荐使用。

用法:

Deque<Integer> deque = new ArrayDeque<>();
deque.offerFirst(1); // 从队首添加元素
deque.offerLast(2);  // 从队尾添加元素
System.out.println(deque.pollFirst()); // 从队首移除并返回,输出1
System.out.println(deque.pollLast());  // 从队尾移除并返回,输出2

4. ConcurrentLinkedQueue

使用场景:

  • 线程安全队列:适用于多线程环境下的非阻塞队列。
  • 高效的并发操作:适合生产者-消费者模型。

用法:

Queue<Integer> concurrentQueue = new ConcurrentLinkedQueue<>();
concurrentQueue.offer(1);
concurrentQueue.offer(2);
System.out.println(concurrentQueue.poll()); // 输出1
System.out.println(concurrentQueue.peek()); // 输出2

5. LinkedBlockingQueue

使用场景:

  • 阻塞队列:适用于生产者-消费者模式,具有容量限制。
  • 线程安全:在高并发场景下使用。

用法:

BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>(2);
blockingQueue.put(1); // 添加元素,如果队列满则阻塞
blockingQueue.put(2);
// blockingQueue.put(3); // 阻塞直到有空间
System.out.println(blockingQueue.take()); // 移除并返回队首元素,输出1

6. ArrayBlockingQueue

使用场景:

  • 固定大小的阻塞队列:比 LinkedBlockingQueue 更高效,适合固定容量的场景。
  • 线程安全:用于线程间通信。

用法:

BlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<>(2);
arrayBlockingQueue.put(1);
arrayBlockingQueue.put(2);
// arrayBlockingQueue.put(3); // 阻塞直到有空间
System.out.println(arrayBlockingQueue.take()); // 输出1

7. PriorityBlockingQueue

使用场景:

  • 线程安全的优先级队列:用于需要优先级的多线程场景。
  • 无界队列:默认容量无限。

用法:

BlockingQueue<Integer> priorityBlockingQueue = new PriorityBlockingQueue<>();
priorityBlockingQueue.put(3);
priorityBlockingQueue.put(1);
priorityBlockingQueue.put(2);
System.out.println(priorityBlockingQueue.take()); // 输出1(按优先级)

8. DelayQueue

使用场景:

  • 延迟队列:用于定时任务调度,只有延迟时间到期后元素才会出队。
  • 任务延迟处理:适合处理带有延迟的任务。

用法:

import java.util.concurrent.*;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

class DelayedTask implements Delayed {
    private long delayTime;
    private long expireTime;

    public DelayedTask(long delayTime) {
        this.delayTime = delayTime;
        this.expireTime = System.currentTimeMillis() + delayTime;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(expireTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        return Long.compare(this.getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS));
    }

    @Override
    public String toString() {
        return "Task with delay: " + delayTime;
    }
}

DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
delayQueue.put(new DelayedTask(3000)); // 延迟3秒
System.out.println("Task added...");
System.out.println(delayQueue.take()); // 等待3秒后输出

9. SynchronousQueue

使用场景:

  • 无缓冲队列:用于直接传递元素,生产者和消费者必须相互等待。
  • 生产者-消费者模型:需要即时传递的场景。

用法:

BlockingQueue<Integer> synchronousQueue = new SynchronousQueue<>();
new Thread(() -> {
    try {
        synchronousQueue.put(1); // 阻塞等待消费者
        System.out.println("Produced 1");
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}).start();

new Thread(() -> {
    try {
        System.out.println("Consumed " + synchronousQueue.take()); // 输出1
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}).start();

总结

队列类型特点使用场景
LinkedListFIFO/双端队列通用队列、小型场景
PriorityQueue优先级排序任务调度
ArrayDeque高效双端队列栈或队列实现
ConcurrentLinkedQueue非阻塞线程安全队列高并发的无界队列
LinkedBlockingQueue有界阻塞队列高并发的生产者-消费者模型
ArrayBlockingQueue固定大小的阻塞队列高并发的生产者-消费者模型
PriorityBlockingQueue线程安全优先级队列带优先级的任务调度
DelayQueue带延迟的队列定时任务
SynchronousQueue无缓冲队列实时任务传递

根据需求选择合适的队列可以大大提高代码的效率和可读性。