阻塞队列(BlockingQueue)
阻塞队列:
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接口。
BlockingQueue接口的实现类
BlockingQUeue的核心方法
一、ArrayBlockingQueue
1、抛出异常:
1 2 3 4 5 6 7 8 9 10 11 12 | BlockingQueue<String> queue = new ArrayBlockingQueue<>(3); // 1、抛出异常:add/remove System. out .println(queue.add( "a" )); System. out .println(queue.add( "b" )); System. out .println(queue.add( "c" )); // 超出队列长度报错:Queue full // System.out.println(queue.add("x")); queue.remove(); queue.remove(); queue.remove(); // 队列中没有元素报错:NoSuchElementException //queue.remove(); |
2、特殊值
1 2 3 4 5 6 7 8 9 10 11 12 | BlockingQueue<String> queue = new ArrayBlockingQueue<>(3); // 2、特殊值:offer/poll System. out .println(queue.offer( "a" )); System. out .println(queue.offer( "b" )); System. out .println(queue.offer( "c" )); // 插入不进去元素会返回false System. out .println(queue.offer( "x" )); System. out .println(queue.poll()); System. out .println(queue.poll()); System. out .println(queue.poll()); // 取不到数据会返回null System. out .println(queue.poll()); |
3、阻塞
1 2 3 4 5 6 7 8 9 10 11 12 | BlockingQueue<String> queue = new ArrayBlockingQueue<>(3); // 3、阻塞 queue.put( "a" ); queue.put( "b" ); queue.put( "c" ); // 队列插入不了数据,会一直卡住 // queue.put("x"); System. out .println(queue.take()); System. out .println(queue.take()); System. out .println(queue.take()); // 检索并删除此队列的头,如有必要,请等待直到元素可用 System. out .println(queue.take()); |
4、超时
1 2 3 4 5 6 7 8 9 10 11 12 | BlockingQueue<String> queue = new ArrayBlockingQueue<>(3); // 3、超时 System. out .println(queue.offer( "a" , 2L, TimeUnit.SECONDS)); System. out .println(queue.offer( "b" , 2L, TimeUnit.SECONDS)); System. out .println(queue.offer( "c" , 2L, TimeUnit.SECONDS)); // 队列已满会等待指定的时间,返回false System. out .println(queue.offer( "x" , 2L, TimeUnit.SECONDS)); System. out .println(queue.poll(2L, TimeUnit.SECONDS)); System. out .println(queue.poll(2L, TimeUnit.SECONDS)); System. out .println(queue.poll(2L, TimeUnit.SECONDS)); // 队列已满会等待指定的时间,返回null System. out .println(queue.poll(2L, TimeUnit.SECONDS)); |
二、SynchronizeousQueue:生产一个消费一个
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 | import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @author zhangzhixi * @date 2021-4-20 22:08 */ public class Demo_05_阻塞队列 { public static void main(String[] args) throws InterruptedException { SynchronousQueue<String> queue = new SynchronousQueue<>(); // 一个线程用来生产 new Thread(() -> { try { System. out .println(Thread.currentThread().getName() + "\t put:" + "a" ); queue.put( "a" ); System. out .println(Thread.currentThread().getName() + "\t put:" + "b" ); queue.put( "b" ); System. out .println(Thread.currentThread().getName() + "\t put:" + "c" ); queue.put( "c" ); } catch (InterruptedException e) { e.printStackTrace(); } }, "AAA" ).start(); // 一个线程用来消费 new Thread(() -> { try { TimeUnit.SECONDS.sleep(3); System. out .println(Thread.currentThread().getName() + "\t释放 " +queue.take()); TimeUnit.SECONDS.sleep(3); System. out .println(Thread.currentThread().getName() + "\t释放 " +queue.take()); TimeUnit.SECONDS.sleep(3); System. out .println(Thread.currentThread().getName() + "\t释放 " +queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } }, "BBB" ).start(); } } |
三、PriorityBlockingQueue:阻塞优先队列
PriorityBlockingQueue是一个无界队列,它没有限制,在内存允许的情况下可以无限添加元素;它又是具有优先级的队列,是通过构造函数传入的对象来判断,传入的对象必须实现comparable接口。
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 | public static void main(String[] args) { // 1、新建一个优先阻塞队列 BlockingQueue<Person> blockingQueue = new PriorityBlockingQueue<>(); Person per = null ; // 2、添加数据 blockingQueue.add( new Person( 6 , "张三" , 20 )); blockingQueue.add( new Person( 5 , "李四" , 20 )); blockingQueue.add( new Person( 1 , "王五" , 28 )); // 3、取出数据 blockingQueue.forEach(System.out::println); } class Person implements Comparable<Person> { private Integer id; private String name; private Integer age; public Person() { } public Person(Integer id, String name, Integer age) { this .id = id; this .name = name; this .age = age; } @Override public int compareTo(Person o) { // 比较规则,先按照age进行从小到大排序,如果年龄一样再按照id进行从小到大排序 if ( this .age.compareTo(o.age) == 0 ) { return this .id.compareTo(o.id); } return this .age.compareTo(o.age); } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\ '' + ", age=" + age + '}' ; } } |
结果:
1 2 3 | Person{id= 5 , name= '李四' , age= 20 } Person{id= 6 , name= '张三' , age= 20 } Person{id= 1 , name= '王五' , age= 28 } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话