java中的原生队列

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<Integer> queue = new PriorityQueue<Integer>(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<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();
}
}
}
}
}

原文地址:https://www.cnblogs.com/farmer-lau/p/10373560.html