阻塞队列的实现原理
lock(ReentrantLock)锁 多个条件(condition)的阻塞控制,使用BlockingQueue封装了根据condition条件阻塞线程的过程,就不用去关心繁琐的await/signal操作了;
阻塞队列的种类
BlockingQueue是个接口,需要使用它的实现之一来实现BlockingQueue;
ArrayBlockingQueue
ArrayBlockingQueue 是一个用数组实现的、有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,它不能够存储无限多数量的元素。
它有一个同一时间能够存储元素数量的上限。你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改)。
此队列按照FIFO(先进先出)的原则对元素进行排序;是一种默认情况下不保证访问者公平的访问队列;
DelayQueue
这是一种支持延时获取元素的无界阻塞队列;
意思就是,在往DelayQueue队列中存入元素时,可以指定:多久才能从队列中获取当前这些元素,即,延时获取;
队列中的元素必须实现 java.util.concurrent.Delayed 接口;
LinkedBlockingQueue
这是一种基于链表的阻塞队列;即内部是以链表结构对其元素进行存储;
与ArrayBlockingQueue类似,此队列也是按照FIFO(先进先出)的原则对元素进行排序;
LinkedBlockingQueue可以高效的处理并发数据,因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着,在高并发的情况下,生产者和消费者可以并行的操作队列中的数据,这样一来大大的提高整个队列的并发性能;
PriorityBlockingQueue
这是一种支持优先级的无界并发队列;无法向这个队列中插入 null 值;默认情况下元素采取自然顺序升序排列;所有插入到该队列的元素必须实现 java.lang.Comparable 接口,因此该队列中的元素的排序规则,也可以自定义;
SynchronousQueue
SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素;
如果该队列已有一个元素的话,试图向队列中插入(Put)一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中取走(take);
同样如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素;
BlockingQueue 阻塞队列的take()和put()方法是线程安全的吗? 多线程下调用take()或者put()方法会出问题吗?
BlockingQueue的三个实现类, 发现对应的方法中都使用了锁, 所以不会出现线程安全问题;主要调用final ReentrantLock lock =this.lock;lock.lockInterruptibly();
lock.await();lock.signal();
lock.lock();lock.unlock();
来实现阻塞和加解锁同步控制;