PriorityBlockingQueue是一个支持优先级的无界阻塞队列,直到系统资源耗尽。默认情况下元素采用自然顺序升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数Comparator来对元素进行排序。但需要注意的是不能保证同优先级元素的顺序。PriorityBlockingQueue也是基于最小二叉堆实现,使用基于CAS实现的自旋锁来控制队列的动态扩容,保证了扩容操作不会阻塞take操作的执行
实现类需要自己实现一个继承了 Comparator 接口的类, 在插入资源时会按照自定义的排序规则来对资源数组进行排序。 其中值大的排在数组后面 ,取值时从数组投开始取
/**
* 生产者
*
*/
public class ExBean implements Comparable<ExBean> {
int id;
String name;
public String getName() {
return name;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public ExBean(int id,String name) {
this.name = name;
this.id = id;
}
@Override
public int compareTo(ExBean exBean) {
return this.id - exBean.getId();
}
@Override
public String toString() {
return "ExBean{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
PriorityBlockingQueue有四个构造方法:
- public PriorityBlockingQueue()
- public PriorityBlockingQueue(int initialCapacity)//
根据initialCapacity来设置队列的初始容量 - public PriorityBlockingQueue(int initialCapacity, Comparator<? super
E> comparator)// 根据initialCapacity来设置队列的初始容量,并根据comparator对象来对数据进行排序 - public PriorityBlockingQueue(Collection<? extends E> c)// 根据集合来创建队列
常用的添加元素函数
- add():若超出了度列的长度会直接抛出异常:
- put():若向队尾添加元素的时候发现队列已经满了会发生阻塞一直等待空间,以加入元素。
- offer():如果发现队列已满无法添加的话,会直接返回false。
从队列中取出并移除头元素的方法
- poll():若队列为空,返回null。
- remove():若队列为空,抛出NoSuchElementException异常。
- take():若队列为空,发生阻塞,等待有元素。
返回队列头列表
- element():返回队列头元素,如果为空则抛出异常NoSuchEleMentException
- peek():返回队列头元素,如果为空则返回null
ExQueueManager.class
public class ExQueueManager {
private static ExQueueManager manager;
private PriorityBlockingQueue<Object> queue ;
private ExQueueManager(){
queue = new PriorityBlockingQueue();
}
public static ExQueueManager getInstance(){
if (null==manager){
synchronized (ExQueueManager.class){
if (null==manager){
manager = new ExQueueManager();
}
}
}
return manager ;
}
/**
* 添加
*
* @param t
* @param <T>
*/
public <T extends Comparable> void add(T t){
queue.add(t);
}
/**
* 取出
*/
public <T extends Comparable> T take(){
try {
if (!queue.isEmpty()){
return (T) queue.take();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null ;
}
public boolean isEmpty(){
return queue.isEmpty();
}
}
消费者
/**
* 消費者
*/
public class ExQueueThread extends Thread {
@Override
public void run() {
super.run();
try {
while (!ExQueueManager.getInstance().isEmpty()){
/*同时取三个 用来消费*/
ExBean t = ExQueueManager.getInstance().take();
ExBean t1 = ExQueueManager.getInstance().take();
ExBean t2 = ExQueueManager.getInstance().take();
Thread.sleep(3000);
Log.v("tag","[ExBean]->"+t.toString());
Log.v("tag","[ExBean]->"+t1.toString());
Log.v("tag","[ExBean]->"+t2.toString());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试结果
private void initQueue() {
for (int i=0;i<10;i++){
ExQueueManager.getInstance().add(new ExBean(i,
"公司大發噶的風格 i="+i));
}
new ExQueueThread().start();
}