1.非阻塞
1.1,PriorityQueue:優先級隊列,存入的元素能夠實現Comparable,從而按照自定義的順序去執行
1.2,LinkedList:雙向鏈表,實現了Dequeue接口
2.阻塞
2.1,ArrayBlockingQueue:數組隊列
a.底層是數組,讀取快,增刪慢
b.指定公平性(是否讓等待最長的隊列先執行),默認不公平
public ArrayBlockingQueue(int capacity, boolean fair),fair:公平
c.建立時必須指定大小
d.先進先出(公平性是另外一個範疇,公平性是相對於隊列的消費者而言的)
2.2,LinkedBlockingQueue:鏈表隊列
a.底層是雙向鏈表,增刪快,讀取慢
b.能夠不指定容量大小,默認Integer.MAX_VALUE
c.沒有公平性一說
d.先進先出(公平性是另外一個範疇,公平性是相對於隊列的消費者而言的)
2.3,PriorityBlockingQueue:優先級隊列
a.須要傳入一個Comparable的實現類,即自定義優先級
b.此隊列是無界隊列,可是能夠指定初始容量,大最大容量沒有限制,插入元素不 會被阻塞
2.4,DelayQueue:延時隊列
a.無界隊列,插入元素不會被阻塞
b.只有當指定的延時時間到了才能從隊列中得到元素數組
3.方法
3.1.阻塞隊列和非阻塞隊列的通用方法
3.1.1增
add(E e):將元素e插入到隊列末尾,若是插入成功,則返回true;若是插入失敗(即 隊列已滿),則會拋出異常;
offer(E e):將元素e插入到隊列末尾,若是插入成功,則返回true;若是插入失敗(即隊列已滿),則返回false;
3.1.2刪
remove():移除隊首元素,若移除成功,則返回true;若是移除失敗(隊列爲空),則會拋出異常;
poll():移除並獲取隊首元素,若成功,則返回隊首元素;不然返回null;
3.1.3查
poll():移除並獲取隊首元素,若成功,則返回隊首元素;不然返回null;
peek():獲取隊首元素,若成功,則返回隊首元素;不然返回nullide
通常用:offer(E e),poll(),peek()線程
2.阻塞隊列的特有方法
3.2.1增
put(E e)方法用來向隊尾存入元素,若是隊列滿,則等待
offer(E e,long timeout, TimeUnit unit)方法用來向隊尾存入元素,若是隊列滿,則等待必定的時間,當時間期限達到時,若是尚未插入成功,則返回false;不然返回true;接口
3.2.2查
take方法用來從隊首取元素,若是隊列爲空,則等待;
poll(long timeout, TimeUnit unit)方法用來從隊首取元素,若是隊列空,則等待必定的時間,當時間期限達到時,若是取到,則返回null;不然返回取得的元素;隊列
4.代碼示例
阻塞隊列不用本身寫線程等待和喚醒的代碼,很方便
1.下面先使用Object.wait()和Object.notify()、非阻塞隊列實現生產者-消費者模式:
class Test {
private int queueSize = 10;
private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(queueSize);ci
public static void main(String[] args) {
Test test = new Test();
Consumer consumer = test.new Consumer();
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
Producer producer = test.new Producer();rem
producer.start();
consumer.start();
}it
class Consumer extends Thread{io
@Override
public void run() {
consume();
}class
private void consume() {
while(true){
synchronized (queue) {
while(queue.size() == 0){
try {
System.out.println("隊列空,等待數據");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
queue.notify();
}
}
queue.poll(); //每次移走隊首元素
queue.notify();
System.out.println("從隊列取走一個元素,隊列剩餘"+queue.size()+"個元素");
}
}
}
}
class Producer extends Thread{
@Override
public void run() {
produce();
}
private void produce() {
while(true){
synchronized (queue) {
while(queue.size() == queueSize){
try {
System.out.println("隊列滿,等待有空餘空間");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
queue.notify();
}
}
queue.offer(1); //每次插入一個元素
queue.notify();
System.out.println("向隊列取中插入一個元素,隊列剩餘空間:"+(queueSize-queue.size()));
}
}
}
}
}
2.下面是使用阻塞隊列實現的生產者-消費者模式:
class Test {
private int queueSize = 10;
private ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(queueSize);
public static void main(String[] args) {
Test test = new Test();
Producer producer = test.new Producer();
Consumer consumer = test.new Consumer();
producer.start();
consumer.start();
}
class Consumer extends Thread{
@Override
public void run() {
consume();
}
private void consume() {
while(true){
try {
queue.take();
System.out.println("從隊列取走一個元素,隊列剩餘"+queue.size()+"個元素");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread{
@Override
public void run() {
produce();
}
private void produce() { while(true){ try { queue.put(1); System.out.println("向隊列取中插入一個元素,隊列剩餘空間:"+(queueSize-queue.size())); } catch (InterruptedException e) { e.printStackTrace(); } } } }}