1、常规队列
实现接口java.util.Queue,常用方法有offer、peek、poll等,分类:
1)LinkedList:常规队列,实现了接口List和Queue
2)PriorityQueue:有序列表,加入到队列中的元素,根据元素的天然排序或java.util.Comparator进行排序
public class PriorityQueueDemo {
public static void main(String[] args) {
//指定排序规则构造有序队列
PriorityQueue<Object> q1 = new PriorityQueue<Object>(num, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
});
//默认构造,使用天然排序
PriorityQueue<Object> q2 = new PriorityQueue<Object>();
}
}
3)ConcurrentLinkedQueue:基于链接节点的、线程安全的队列,并发访问不需要同步
2、阻塞队列
实现接口java.util.concurrent.BlockingQueue,通过put添加数据,没有空间时阻塞,通过take获取数据,没有数据时阻塞
1)ArrayBlockingQueue:数组支持的有界队列
public class BlockingQueueDemo {
private BlockingQueue<String> queue = new ArrayBlockingQueue<String>(num);
public static void main(String[] args) {
BlockingQueueDemo demo = new BlockingQueueDemo();
Productor p = demo.new Productor();
Consumer c = demo.new Consumer();
p.start();
c.start();
}
class Productor extends Thread{
public void run(){
try {
//队列添加数据
queue.put("...");
} catch (InterruptedException e) {
//异常处理
}
}
}
class Consumer extends Thread{
public void run(){
try {
//从队列获取数据
String str = queue.take();
} catch (InterruptedException e) {
//异常处理
}
}
}
}
2)LinkedBlockingQueue: 链表支持的可选有界队列,用法同ArrayBlockingQueue,只是后台存储方式不同
3)PriorityBlockingQueue:由优先级堆支持的无界优先级队列
4)DelayQueue:由优先级堆支持的、基于时间的调度队列,加入到队列中的元素必须实现新的Delayed接口,主要实现2个方法getDelay(TimeUnit unit)和compareTo(Delayed d),其中getDelay方法返回的值应该是动态的,如果值固定的话,是负值还好说,可以直接获取,如果是正值,获取数据时将一直阻塞,参照源码:
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
E first = q.peek();
if (first == null) {
available.await();
} else {
long delay = first.getDelay(TimeUnit.NANOSECONDS);
if (delay > 0) {
long tl = available.awaitNanos(delay);
} else {
E x = q.poll();
assert x != null;
if (q.size() != 0)
available.signalAll(); // wake up other takers
return x;
}
}
}
} finally {
lock.unlock();
}
}
因为队列的大小没有界限,使得添加可以立即返回,但是在延迟时间过去之前,不能从队列中取出元素。如果多个元素完成了延迟,那么最早失效/失效时间最长的元素将第一个取出
5)SynchronousQueue:同步队列,每个插入操作必须等待另一个线程的对应移除操作,反之亦然。