ArrayBlockingQueue
package Juc;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* 阻塞队列
* 1.阻塞有好处 对海底捞而言设立侯餐区
* 2.不得不阻塞 对上医院科室之前的我们取挂号
* 队列是Collection接口-->Queue接口-->BlockingQueue接口
*
* BlockingQueue七大实现类
*
*
* 1.ArrayBlockingQueue:基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长的数组,FIFO(先进先出)
* 以便缓存队列中的数据对象,其内部没实现读写分离,也就意味着生产和消费者不能完全并行。
* 长度是需要定义的,可以指定先进先出或者先进后出,因为长度是需要定义的,所以也叫有界队列,在很多场合非常适合使用。
*
* 2.LinkedBlockingQueue:基于链表的阻塞队列,同ArrayBlockingQueue类似,吞吐量大于ArrayBlockingQueue,(默认大小是Interger.max_value)
* 其内部也维持着一个数据缓冲队列(该队列由一个链表构成),FIFO(先进先出)
* LinkedBlockingQueue之所以能够高效地处理并发数据,是因为其内部实现采用分离锁(读写分离两个锁),
* 从而实现生产者和消费者操作完全并行运行。需要注意一下,它是一个无界队列。
*
* 3.PriorityBlockingQueue : 支持优先级排序的无界阻塞队列
* PriorityBlockingQueue:基于优先级别的阻塞队列
* (优先级的判断通过构造函数传入的Compator对象来决定,也就是说传入队列的对象必须实现Comparable接口),
* 在实现PriorityBlockingQueue时,内部控制线程同步的锁采用的是公平锁,需要注意的是它也是一个无界的队列。
*
* 4. DelayQueue:使用优先级队列实现的延时无界阻塞队列。
* DelayQueue:带有延迟时间的Queue,其中的元素只有当其指定的延迟时间到了,
* 才能够从队列中获取到该元素。DelayQueue中的元素必须先实现Delayed接口,
* DelayQueue是一个没有大小限制的队列,应用场景很多,比如对缓存超时的数据进行移除、任务超时处理、空闲连接的关闭等等。
*
* 5. SynchronousQueue:一种没有缓冲的队列,生产者产生的数据直接会被消费者获取并且立刻消费。否则插入操作一直处于阻塞状态,吞吐量高于
*
* 6.LinkedTransferQueue:由链表结构组成的无界阻塞队列
*
* 7.LinkedBlockingDueue:由链表结构组成的双向阻塞队列
*
*
*/
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
//当阻塞队列满了,再往队列add插入元素,会抛出IllegalStateException: Queue full
//当阻塞队列空时,再往队列里remove()移除元素会抛出NoSuchElementException
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
// blockingQueue.add("x"); //---> Exception in thread "main" java.lang.IllegalStateException: Queue full
// System.out.println(blockingQueue.element()); //检查队首元素
System.out.println(blockingQueue.remove()); //FIFO 先进先出的清空队列
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.element());
// blockingQueue.remove(); //Exception in thread "main" java.util.NoSuchElementException
/*=======================================================================================*/
BlockingQueue<String> bQ = new ArrayBlockingQueue<>(3);
//offer();和peek();和poll();插入队列元素出界返回false or null
//插入方法,成功返回true失败false
//移除方法,成功返回队列的元素,队列没元素返回空
System.out.println(bQ.offer("a"));
System.out.println(bQ.offer("b"));
System.out.println(bQ.offer("c"));
//System.out.println(bQ.offer("x")); //false
System.out.println(bQ.peek()); //探测队首元素
System.out.println(bQ.poll()); //依次弹出队首元素
System.out.println(bQ.poll());
System.out.println(bQ.poll());
System.out.println(bQ.poll()); //null
/*=======================================================================================*/
//当阻塞队列满时,生产者线程继续网队列put元素,队列会一直种颜色生产线程直到put数据or网络中断退出
//当阻塞队列空时,消费者线程会试图从队列take元素,队列会一直阻塞消费者线程直到队列可用。
BlockingQueue<String> bq = new ArrayBlockingQueue<>(3);
/* bq.put("a");
bq.put("b");
bq.put("c");
System.out.println("=================");
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
bq.take();
bq.take();
bq.take();
bq.take();
*/
/*==========================================================================================*/
//未满直接插入,当阻塞队列满时,队列会阻塞生产者线程一段时间,超时后生产者线程会退出。
//当阻塞队列空时,队列会阻塞消费者线程一定时间,超时后消费者线程会退出。
BlockingQueue<String> b = new ArrayBlockingQueue<>(3);
System.out.println(b.offer("a", 2L, TimeUnit.SECONDS));
System.out.println(b.offer("b", 2L, TimeUnit.SECONDS));
System.out.println(b.offer("c", 2L, TimeUnit.SECONDS));
System.out.println(b.offer("d", 2L, TimeUnit.SECONDS));
}
}