阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。
对于许多线程问题,可以通过使用一个或多个队列以优雅且安全的方式将其形式化。使用队列可以安全地从一个线程向另一个线程传递数据。例如,银行转账程序,转账线程将转账指令对象插入一个队列中,而不是直接访问银行对象。另一个线程从队列中取出指令执行转账。只有该线程可以访问该银行对象的内部。因此就不需要同步了。
当试图向队列添加元素而队列已满,或是想从队列中移出元素而队列为空时,阻塞队列导致线程阻塞。工作者线程可以周期性地将中间结果存储到阻塞队列中。其他的工作者线程移出中间结果并进一步加以修改。队列会自动的平衡负载。在相邻的线程存在快慢的情况下会进行平衡。
Java中的阻塞队列
java.util.concurrent包提供了几种不同形式的阻塞队列,如数组阻塞队列ArrayBlockingQueue、链表阻塞队列LinkedBlockingQueue、优先级阻塞队列PriorityBlockingQueue和延时队列DelayQueue等,下面简单介绍一下这几个阻塞队列:
数组阻塞队列:ArrayBlockingQueue是一个由数组支持的有界阻塞队列,内部维持着一个定长的数据缓冲队列(该队列由数组构成),此队列按照先进先出(FIFO)的原则对元素进行排序,在构造时需要给定容量。ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
对于数组阻塞队列,可以选择是否需要公平性,所谓公平访问队列是指阻塞的所有生产者线程或消费者线程,当队列可用时,可以按照阻塞的先后顺序访问队列,即先阻塞的生产者线程,可以先往队列里插入元素,先阻塞的消费者线程,可以先从队列里获取元素。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。
“我们相信人人都可以成为一个IT大神,现在开始,选择一条阳光大道,助你入门,学习的路上不再迷茫。这里是北京尚学堂,初学者转行到IT行业的聚集地。"