阻塞队列实现原理

1.阻塞队列实现原理
阻塞队列与普通队列的区别在于,阻塞队列提供了可阻塞的put和take方法。如果队列是空的,消费者使用take方法从队列中获取数据就会被阻塞,直到队列有数据可用;当队列是满的,生产者使用put方法向队列里添加数据就会被阻塞,直到队列中数据被消费有空闲位置可用
阻塞队列实现原理_第1张图片
2.JUC提供了7种适合与不同应用场景的阻塞队列。
1)ArrayBlockingQueue:基于数组实现的有界阻塞队列。
2)LinkedBlockingQueue:基于链表实现的有界阻塞队列。
3)PriorityBlockingQueue:支持按优先级排序的无界阻塞队列。
4)DelayQueue:优先级队列实现的无界阻塞队列。
5)SynchronousQueue:不存储元素的阻塞队列。
6)LinkedTransferQueue:基于链表实现的无界阻塞队列。
7)LinkedBlockingDeque:基于链表实现的双向无界阻塞队列。
7个阻塞队列全部实现了BlockingQueue接口,插入和移除元素分别各提供了4种处理方式。

插入操作:添加元素到队列中。
1)add(e):当队列满的时候,继续插入元素会抛出IllegalStateException("Queue full")异常。
2)offer(e):当队列满的时候,继续插入元素不会阻塞,直接返回false。如果插入成功则返回true。
3)put(e):当队列满的时候,继续插入元素线程会被一直阻塞直到队列有空闲位置可用时为止。
4)offer(e,time,unit):当队列满的时候,调用该方法的线程会被阻塞一段时间,如果超过指定时间还未添加成功,线程直接退出。

移除操作:从队列中移除元素。
1)remove():当队列为空时,调用该方法元素会抛出NoSuchElementException异常。2)poll():当队列为空时,调用该方法不会阻塞,直接返回null。当队列不为空时,则从队列中取出一个元素。
3)take():当队列为空时,调用该方法会被一直阻塞直到队列有数据可用时为止。
4)poll(time,unit):当队列为空时,调用该方法的线程会被阻塞一段时间,如果超过指定时间队列仍没有数据可用,直接返回null。当然,如果是向无界阻塞队列中插入元素,因为无界队列永远不可能会出现满的情况,所以使用put或offerr(e,time,unit)方法永远不会被阻塞。
ArrayBlockingQueue和LinkedBlockingQueue是最常用的阻塞队列,一般情况下,这两个类基本上能满足大部分的LinkedBlockingQueue和ArrayBlockingQueue两个队列的主要区别如下。
1)底层数据结构不同。ArrayBlockingQueue基于数组实现,使用数组存储元素。LinkedBlockingQueue基于单链表实现,使用链表存储元素。
2)队列容量不同。ArrayBlockingQueue构造时必须指定容量,且后续不能改变。LinkedBlockingQueue既可以指定大小,也可以不指定,默认使用一个类似无界的容量(Integer. MAX_VALUE)。
3)ArrayBlockingQueue可以使用公平/非公平锁策略,而LinkedBlockingQueue只能使用非公平策略。ArrayBlockingQueue入队和出队公用一把全局ReentrantLock锁;LinkedBlockingQueue出队和入队分别使用独立的锁,所以LinkedBlockingQueue的并发性能要比ArrayBlockingQueue好生产者和消费者场景的需要

你可能感兴趣的:(面试,多线程,java,java)