一、队列的定义

我们都知道队列(Queue)是一种先进先出(FIFO)的数据结构,Java中定义了java.util.Queue接口用来表示队列。Java中的QueueListSet属于同一个级别接口,它们都是继承于Collection接口。

Java中还定义了一种双端队列java.util.Deque,我们常用的LinkedList就是实现了Deque接口。

下面我们看一下类的定义:

Queue & Deque
public interface Queue<E> extends Collection<E> {

    boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

    E peek();
}
public interface Deque<E> extends Queue<E> {

    void addFirst(E e);

    void addLast(E e);

    boolean offerFirst(E e);

    boolean offerLast(E e);

    E removeFirst();

    E removeLast();

    E pollFirst();

    E pollLast();

    E getFirst();

    E getLast();

    E peekFirst();

    E peekLast();

    boolean removeFirstOccurrence(Object o);

    boolean removeLastOccurrence(Object o);

    // *** Queue methods ***

    boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

    E peek();

    // *** Stack methods ***

    void push(E e);

    E pop();

	// *** Collection methods ***

    boolean remove(Object o);

    boolean contains(Object o);

    public int size();

    Iterator<E> iterator();

    Iterator<E> descendingIterator();

}

二、队列的实现

Java中对于队列的实现分为非阻塞阻塞两种。

$ 非阻塞队列分为如下:

  • LinkedList

    LinkedList是双相链表结构,在添加和删除元素时具有比ArrayList更好的性能。但在 Get 与 Set 方面弱于ArrayList。当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比。

  • PriorityQueue

    PriorityQueue维护了一个有序列表,存储到队列中的元素会按照自然顺序排列。当然,我们也可以给它指定一个实现了 java.util.Comparator 接口的排序类来指定元素排列的顺序。

  • ConcurrentLinkedQueue

    ConcurrentLinkedQueue 是基于链接节点的并且线程安全的队列。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大小 ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。

$ 阻塞队列分为如下:

阻塞队列定义在了java.util.concurrent包中,java.util.concurrent.BlockingQueue 继承了Queue接口,它有 5 个实现类,分别是:

  • ArrayBlockingQueue

    一个内部由数组支持的有界队列。初始化时必须指定队列的容量,还可以设置内部的ReentrantLock是否使用公平锁。但是公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队列,此队列按 FIFO(先进先出)原则对元素进行排序。

    它的思想就是如果BlockQueue是空的,那么从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒。同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作。

  • **LinkedBlockingQueue **

    一个内部由链接节点支持的可选有界队列。初始化时不需要指定队列的容量,默认是Integer.MAX_VALUE ,也可以看成容量无限大。此队列按 FIFO(先进先出)排序元素 。

  • PriorityBlockingQueue

    一个内部由优先级堆支持的无界优先级队列。PriorityBlockingQueue是对 PriorityQueue的再次包装,队列中的元素按优先级顺序被移除。

  • DelayQueue

    一个内部由优先级堆支持的、基于时间的调度队列。队列中存放Delayed元素,只有在延迟期满后才能从队列中提取元素。当一个元素的getDelay()方法返回值小于等于0时才能从队列中poll中元素,否则poll()方法会返回null。  

  • SynchronousQueue

    一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

下面简单介绍一下其中常用的方法:

  • add         增加一个元索                      如果队列已满,则抛出一个IIIegaISlabEepeplian异常   
  • remove   移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常   
  • element  返回队列头部的元素              如果队列为空,则抛出一个NoSuchElementException异常   
  • offer        添加一个元素并返回true        如果队列已满,则返回false   
  • poll          移除并返问队列头部的元素    如果队列为空,则返回null   
  • peek        返回队列头部的元素              如果队列为空,则返回null   
  • put          添加一个元素                       如果队列满,则阻塞   
  • take         移除并返回队列头部的元素   如果队列为空,则阻塞

三、示例

package com.ysc.thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; public class BlockingQueueTest { public static void main(String[] args) {
final BlockingQueue queue = new ArrayBlockingQueue(3);
for(int i=0;i<2;i++){
new Thread(){
public void run(){
while(true){
try {
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName() + "准备放数据!");
queue.put(1);
System.out.println(Thread.currentThread().getName() + "已经放了数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
} new Thread(){
public void run(){
while(true){
try {
//将此处的睡眠时间分别改为100和1000,观察运行结果
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName() + "已经取走数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
package com.ysc.thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class BlockingQueueCondition { public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
final Business business = new Business();
service.execute(new Runnable(){
@Override
public void run() {
for(int i=0;i<50;i++){
business.sub();
}
}
}); for(int i=0;i<50;i++){
business.main();
}
} } class Business {
BlockingQueue subQueue = new ArrayBlockingQueue(1);
BlockingQueue mainQueue = new ArrayBlockingQueue(1);
//这里是匿名构造方法,只要new一个对象都会调用这个匿名构造方法,它与静态块不同,静态块只会执行一次,
//在类第一次加载到JVM的时候执行
//这里主要是让main线程首先put一个,就有东西可以取,如果不加这个匿名构造方法put一个的话程序就死锁了
{
try {
mainQueue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void sub(){
try {
mainQueue.take();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
subQueue.put(1);
} catch (Exception e){
}
} public void main() {
try {
subQueue.take();
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
mainQueue.put(1);
} catch (Exception e){
}
}
}

Java 中的队列 Queue的更多相关文章

  1. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  2. Java中使用队列Queue

    示例代码: Queue<Integer> queue = new LinkedList<Integer>(); for (int i = 1; i <= 100; i + ...

  3. java中有界队列的饱和策略(reject policy)

    文章目录 AbortPolicy DiscardPolicy DiscardOldestPolicy CallerRunsPolicy 使用Semaphore java中有界队列的饱和策略(rejec ...

  4. java中使用队列:java.util.Queue (转)

    Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Queue接 口.Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类 ...

  5. java中的各种Queue

    java中的各种并发Queue可以归为以下的几种: ConcurrentLinkedQueue: 一个由链表结构组成的非阻塞队列 ArrayBlockingQueue :一个由数组结构组成的有界阻塞队 ...

  6. 一篇图看清Java中的各种Queue

    说到数据结构,我们大概可以列出这么几个:数组,链表,栈,队列,集合,哈希表. 其中 队列 作为一个常用的数据结构,在Java中也有各种形式的实现. 顶级接口为java.util.queue. java ...

  7. Java线程安全队列Queue实现原理

    原文链接:https://www.cnblogs.com/DreamRecorder/p/9223016.html 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.J ...

  8. Java中的队列:java.util.Queue接口

    队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作. Queue接口与List.Set同一级别,都是继承了Collection接口.Linked ...

  9. java中使用队列:java.util.Queue

    在java5中新添加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口.Queue使用时要尽量避免Collection的add()和 ...

随机推荐

  1. Ubuntu下安装pycharm并设置快捷方式

    作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7070327.html Ubuntu下安装pycharm并设置快捷方式 下载P ...

  2. 【python-crypto】导入crypto包失败的情况,怎么处理

    [python-crypto]导入crypto包失败的情况,怎么处理 是因为你自己安装的python的版本太高,所以自己降版本吧,捣鼓了一下午 pip install crypto pip insta ...

  3. Foundation-NSOperation-NSInvocationOperation/NSBlockOperation/NSOperationQueue

    iOS多线程编程技术之NSThread.Cocoa NSOperation.GCD 线程之间的通信 iOS开发系列--并行开发其实很容易 GCD由浅入深学习 iOS多线程NSOperation/Que ...

  4. 跟哥走,带你玩转Surface 2

    以为自己是数码控?觉得自己买了Surface就无所不能?别逗了!来看哥怎么玩平板,也让你们这些小虾米看看,什么才叫“玩转”! 新技能Get:密码不在用键盘 什么?每次开机你还要输入一长串密码?都什么年 ...

  5. POJ1644状态转移的思想——排列组合

    m个物品放n个盒子,盒子物品都相同,问你放的方法总数是多少 看着像个排列组合,算着算着就发现我排列组合都忘得差不多啦,哎,什么时候能打败遗忘呢 然后想用dp做,但是转移的方面没有想好 看了看题解感觉这 ...

  6. java数据库编程(未整理完,待续)

    java使用数据库可以借助jdbc这个中间媒介.本文将介绍如何使用jdbc连接数据库,数据库的基本操作和jdbc的事物处理. 1 连接数据库 一般java连接数据库,都有几个步骤: 0.导入相应的驱动 ...

  7. http发送请求方式;分为post和get两种方式

    http发送请求方式:分为post和get两种方式

  8. 2.Django模型

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...

  9. Delphi-idHttp-Post JSON用法 good

    从国外网站抄来的代码 Delphi source: http := TIdHttp.Create(nil);http.HandleRedirects := True;//允许头转向http.ReadT ...

  10. 分形之花篮(Flower Basket)

    这一篇展示的图形与上一篇文章分形之皇冠(Crown)很相似. 核心代码: static void FractalFlowerBasket(const Vector3& vStart, cons ...