- BlockingQueue和JDK集合包中的Queue接口兼容,同时在其基础上增加了阻塞功能
- offer(E e):如果队列没满,返回true,如果队列已满,返回false(不阻塞)
- offer(E e, long timeout, TimeUnit unit):可以设置阻塞时间,如果队列已满,则进行阻塞。超过阻塞时间,则返回false
- put(E e):队列没满的时候是正常的插入,如果队列已满,则阻塞,直至队列空出位置
- poll():如果有数据,出队,如果没有数据,返回null (不阻塞)
- poll(long timeout, TimeUnit unit):可以设置阻塞时间,如果没有数据,则阻塞,超过阻塞时间,则返回null
- take():队列里有数据会正常取出数据并删除;但是如果队列里无数据,则阻塞,直到队列里有数据
- ArrayBlockingQueue 基于数组的有界阻塞队列
- 利用 ReentrantLock 实现线程安全(只能有一个线程可以进行入队或者出队操作)
- 利用了Lock锁的Condition通知机制进行阻塞控制(notEmpty、notFull)
- LinkedBlockingQueue 基于单链表的无界阻塞队列
- 读写分离(只能从head取元素,从tail添加元素):采用两把锁(putLock、takeLock)的锁分离技术实现入队出队互不阻塞
- SynchronousQueue 没有数据缓冲(容量为0)的 BlockingQueue :它所做的就是直接传递
- 每次取数据都要先阻塞,直到有数据被放入
- 每次放数据的时候也会阻塞,直到有消费者来取
- PriorityBlockingQueue 基于数组(二叉堆)的无界优先级阻塞队列(默认长度是11,虽然指定了数组的长度,但是可以无限的扩充)
- 每次出队都返回优先级别最高的或者最低的元素(不能保证同优先级元素的顺序)
- 默认情况下元素采用自然顺序升序排序(也可以通过构造函数来指定Comparator来对元素进行排序)
- DelayQueue 基于优先队列 PriorityQueue 的支持延时获取元素的无界队阻塞队列
- 元素必须实现 Delayed 接口( Delayed 接口又继承了 Comparable 接口)
- 在创建元素时可以指定多久才可以从队列中获取当前元素,只有在延迟期满时才能从队列中提取元素
- 按照延迟时间的长短来排序,下一个即将执行的任务会排到队列的最前面
- 获取元素,先获取到锁对象,然后获取最早过期的元素(但是并不从队列中弹出元素)
- 判断最早过期元素是否为空(如果为空则直接让当前线程无限期等待状态,并且让出当前锁对象)
- 如果不为空:获取最早过期元素的剩余过期时间(如果已经过期则直接返回当前元素)
- 如果没有过期(剩余时间还存在),则先获取Leader对象,如果Leader已经有线程在处理,则当前线程进行无限期等待,如果Leader为空,则首先将Leader设置为当前线程,并且让当前线程等待剩余时间
- 最后将Leader线程设置为空,并且队列有内容则唤醒一个等待的队列
- 线程池对于阻塞队列的选择
- FixedThreadPool(SingleThreadExecutor 同理)选取的是 LinkedBlockingQueue
- CachedThreadPool 选取的是 SynchronousQueue
- ScheduledThreadPool(SingleThreadScheduledExecutor同理)选取的是延迟队列
- 选择策略:
- 功能 PriorityBlockingQueue 优先级;DelayQueue 延时
- 容量:SynchronousQueue 容量是0;DelayQueue 容量是Integer.MAX_VALUE
- 能否扩容:ArrayBlockingQueue 不能扩容;PriorityBlockingQueue 可以动态扩容
- 内存结构:ArrayBlockingQueue 数组的空间利用率更高
- 性能:LinkedBlockingQueue 读写分离;SynchronousQueue 直接传递
上一篇
Java并发-CAS & Atomic
2024-06-13
下一篇
Java并发-AQS
2024-06-13