Java如何用Queue实现FIFO队列?
Java中Queue接口不提供默认FIFO阻塞行为,具体FIFO特性取决于实现类:ArrayDeque(推荐)、ConcurrentLinkedQueue或LinkedBlockingQueue等,需按线程安全与阻塞需求选择。
Java中Queue接口不提供默认FIFO阻塞行为,具体FIFO特性取决于实现类:ArrayDeque(推荐)、ConcurrentLinkedQueue或LinkedBlockingQueue等,需按线程安全与阻塞需求选择。

Java里Queue接口默认不提供FIFO的阻塞行为
Java的Queue接口本身只是定义了入队(add/offer)、出队(remove/poll)、查看头元素(element/peek)等契约,并不保证线程安全,也不强制FIFO——它只是“建议”实现为FIFO。实际是否FIFO,取决于你选的具体实现类。
常见误区是直接用new Queue<>(),这根本不能编译,因为Queue是接口。必须选一个实现类:
LinkedList:非线程安全,FIFO,适合单线程或已加锁场景ArrayDeque:非线程安全,FIFO,性能优于LinkedList(推荐作为默认选择)ConcurrentLinkedQueue:线程安全,无界,FIFO,但size()不是O(1)LinkedBlockingQueue:线程安全,可选有界/无界,FIFO,支持阻塞操作(如take())
ArrayDeque比LinkedList更适合做普通FIFO队列
ArrayDeque底层用循环数组,offer()和poll()平均时间复杂度都是O(1),内存局部性好;而LinkedList是双向链表,每次操作要分配/释放节点对象,GC压力大,且缓存不友好。
除非你需要在队列中间插入或删除(这不是Queue接口的用途),否则别选LinkedList当队列用。它被设计成List和Deque双实现,但作为队列纯属“能用,不优”。
Queuequeue = new ArrayDeque<>(); queue.offer("first"); queue.offer("second"); System.out.println(queue.poll()); // 输出 "first" System.out.println(queue.poll()); // 输出 "second"
别在多线程环境里直接用ArrayDeque或LinkedList
这两个类都不保证线程安全。多个线程同时调用offer()和poll()可能引发数据错乱、丢失元素,甚至ConcurrentModificationException(尤其遍历时)。
如果需要线程安全的FIFO队列,按场景选:
- 高吞吐、不关心阻塞 → 用
ConcurrentLinkedQueue - 需要阻塞等待(比如生产者-消费者模型)→ 用
LinkedBlockingQueue,并明确指定容量避免无限增长 - 需要公平锁或更多控制 → 考虑
PriorityBlockingQueue(注意:它不是FIFO!)或自己包装加锁
错误示范:static Queue —— 多线程下必出问题。
offer()和add()的区别常被忽略
两者都用于入队,但异常策略不同:
add():失败时抛IllegalStateException(比如有界队列满时)offer():失败时返回false,更利于程序判断和恢复
同理,remove() vs poll()(空队列时前者抛NoSuchElementException,后者返回null),element() vs peek()(前者抛异常,后者返回null)。
日常编码中,优先用offer()/poll()/peek(),它们更健壮,也符合“队列可能满或空”的现实假设。
FIFO只是Queue的一种语义约定,Java不会替你校验实现是否真按顺序进出;选错实现类、忽略线程安全、混淆add和offer的异常行为,这三个点最容易在真实项目里埋雷。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















