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:同步隊列,每個插入操作必須等待另一個線程的對應移除操作,反之亦然。