Queue接口不能直接实例化,必须使用LinkedList、PriorityQueue或LinkedBlockingQueue等实现类;LinkedBlockingQueue的capacity参数影响阻塞行为与内存安全;poll()返回null而take()会阻塞;size()在高并发下不可靠,不宜用作条件判断。

Queue接口不能直接new,必须用实现类
Java里Queue是接口,不是具体类,写new Queue()会编译报错。常见误操作是想快速测试队列行为,却卡在实例化这步。实际要用它的实现类,比如LinkedList(非线程安全)、PriorityQueue(带排序)、或者LinkedBlockingQueue(线程安全、阻塞式)。
选择依据主要看场景:
- 单线程、简单FIFO:用
LinkedList或ArrayDeque(后者性能更好) - 多线程、需要等待入队/出队:必须用
LinkedBlockingQueue这类阻塞队列 - 需要按优先级取元素:选
PriorityQueue,但注意它不保证线程安全
LinkedBlockingQueue的capacity参数不是可有可无
LinkedBlockingQueue构造时可以传一个int capacity,比如new LinkedBlockingQueue(10)。这个值决定了队列最大长度,一旦满,后续put()会阻塞;如果没设(用无参构造),默认容量是Integer.MAX_VALUE,看起来“无限”,但实际可能引发OOM——特别是生产者远快于消费者时,任务持续堆积。
典型踩坑场景:
立即学习“Java免费学习笔记(深入)”;
- 用无参构造做消息缓冲,系统负载升高后内存暴涨
- 设了capacity但没配好监控,队列满后
put()线程一直挂起,下游处理延迟飙升 - 和
offer()混用:它不会阻塞,返回false,但业务代码没判断返回值,导致任务静默丢失
poll() vs take():空队列时的行为差异直接影响线程控制
从LinkedBlockingQueue取元素,poll()和take()看着相似,但空队列时表现完全不同:
ECTouch是上海商创网络科技有限公司推出的一套基于 PHP 和 MySQL 数据库构建的开源且易于使用的移动商城网店系统!应用于各种服务器平台的高效、快速和易于管理的网店解决方案,采用稳定的MVC框架开发,完美对接ecshop系统与模板堂众多模板,为中小企业提供最佳的移动电商解决方案。ECTouch程序源代码完全无加密。安装时只需将已集成的文件夹放进指定位置,通过浏览器访问一键安装,无需对已有
Queueq = new LinkedBlockingQueue<>(); q.poll(); // 立即返回 null q.take(); // 无限期阻塞,直到有元素或被中断
这个差异决定你是否要自己写轮询逻辑:
- 用
poll()就得加while循环+Thread.sleep(),容易写成忙等或响应慢 - 用
take()更简洁,但必须处理InterruptedException,且线程被中断时会抛异常,不捕获会导致线程意外退出 - 生产环境推荐
take()+ 正确的中断处理,避免资源泄漏
LinkedBlockingQueue的size()在高并发下不准,别用它做条件判断
LinkedBlockingQueue.size()返回的是当前元素个数,但它内部用的是AtomicInteger计数,看似线程安全。问题在于:这个值只是调用瞬间的快照,之后立刻可能被其他线程修改。拿它做判断极易出错,比如:
if (queue.size() < 10) {
queue.put(item); // 这里可能因并发导致实际超限
}
更糟的是,size()在某些实现里(如ConcurrentLinkedQueue)甚至不保证精确,只保证“估计值”。对LinkedBlockingQueue来说,真正可靠的边界控制只能靠put()阻塞机制本身,或者用offer(E, timeout, unit)配合超时重试。
真正需要感知队列水位时,建议用JMX暴露remainingCapacity(),而不是在业务逻辑里反复查size()。









