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():获取队首元素,若成功,则返回队首元素;否则返回null
一般用: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 queue = new PriorityQueue(queueSize);
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();
producer.start(); consumer.start(); }
class Consumer extends Thread{
@Override public void run() { consume(); }
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 queue = new ArrayBlockingQueue(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(); } } } } }