1、在java5中新增加了java.util.Queue接口,用以支持队列的常见操作。Queue接口与List、Set同一级别,都是继承了Collection接口。
Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优
点是通过返回值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常。 如果要使用前端而不移出该元素,使用
element()或者peek()方法。

2、值得注意的是LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。

3、LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。

4、队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就是说,队列以一种先进先出的方式管理数据,如果你试图向一个 已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具。工作者线程可 以定期地把中间结果存到阻塞队列中而其他工作者线线程把中间结果取出并在将来修改它们。队列会自动平衡负载。如果第一个线程集运行得比第二个慢,则第二个 线程集在等待结果时就会阻塞。如果第一个线程集运行得快,那么它将等待第二个线程集赶上来。下表显示了jdk1.5中的阻塞队列的操作:

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

remove、element、offer 、poll、peek 其实是属于Queue接口。

5、阻塞队列的操作可以根据它们的响应方式分为以下三类:aad、removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时 抛出异常。当然,在多线程程序中,队列在任何时间都可能变成满的或空的,所以你可能想使用offer、poll、peek方法。这些方法在无法完成任务时 只是给出一个出错示而不会抛出异常。

6、注意:poll和peek方法出错进返回null。因此,向队列中插入null值是不合法的。

7、

还有带超时的offer和poll方法变种,例如,下面的调用:
boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
尝试在100毫秒内向队列尾部插入一个元素。如果成功,立即返回true;否则,当到达超时进,返回false。同样地,调用:
Object head = q.poll(100, TimeUnit.MILLISECONDS);
如果在100毫秒内成功地移除了队列头元素,则立即返回头元素;否则在到达超时时,返回null。

最后,我们有阻塞操作put和take。put方法在队列满时阻塞,take方法在队列空时阻塞。

java.ulil.concurrent包提供了阻塞队列的4个变种。默认情况下,LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。

ArrayBlockingQueue在构造时需要指定容量, 并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队 列,此队列按 FIFO(先进先出)原则对元素进行排序。

PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元 素要具有比较能力。

最后,DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。 下面是延迟接口:

Java代码
public interface Delayed extends Comparable<Delayed>{
long getDelay(TimeUnit unit);
}

放入DelayQueue的元素还将要实现compareTo方法,DelayQueue使用这个来为元素排序。

 Java代码
public class BlockingQueueTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter base directory (e.g. /usr/local/jdk5.0/src): ");
String directory = in.nextLine();
System.out.print("Enter keyword (e.g. volatile): ");
String keyword = in.nextLine(); final int FILE_QUEUE_SIZE = 10;// 阻塞队列大小
final int SEARCH_THREADS = 100;// 关键字搜索线程个数 // 基于ArrayBlockingQueue的阻塞队列
BlockingQueue<File> queue = new ArrayBlockingQueue<File>(
FILE_QUEUE_SIZE); //只启动一个线程来搜索目录
FileEnumerationTask enumerator = new FileEnumerationTask(queue,
new File(directory));
new Thread(enumerator).start(); //启动100个线程用来在文件中搜索指定的关键字
for (int i = 1; i <= SEARCH_THREADS; i++)
new Thread(new SearchTask(queue, keyword)).start();
}
}
class FileEnumerationTask implements Runnable {
//哑元文件对象,放在阻塞队列最后,用来标示文件已被遍历完
public static File DUMMY = new File(""); private BlockingQueue<File> queue;
private File startingDirectory; public FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {
this.queue = queue;
this.startingDirectory = startingDirectory;
} public void run() {
try {
enumerate(startingDirectory);
queue.put(DUMMY);//执行到这里说明指定的目录下文件已被遍历完
} catch (InterruptedException e) {
}
} // 将指定目录下的所有文件以File对象的形式放入阻塞队列中
public void enumerate(File directory) throws InterruptedException {
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory())
enumerate(file);
else
//将元素放入队尾,如果队列满,则阻塞
queue.put(file);
}
}
}
class SearchTask implements Runnable {
private BlockingQueue<File> queue;
private String keyword; public SearchTask(BlockingQueue<File> queue, String keyword) {
this.queue = queue;
this.keyword = keyword;
} public void run() {
try {
boolean done = false;
while (!done) {
//取出队首元素,如果队列为空,则阻塞
File file = queue.take();
if (file == FileEnumerationTask.DUMMY) {
//取出来后重新放入,好让其他线程读到它时也很快的结束
queue.put(file);
done = true;
} else
search(file);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
}
}
public void search(File file) throws IOException {
Scanner in = new Scanner(new FileInputStream(file));
int lineNumber = 0;
while (in.hasNextLine()) {
lineNumber++;
String line = in.nextLine();
if (line.contains(keyword))
System.out.printf("%s:%d:%s%n", file.getPath(), lineNumber,
line);
}
in.close();
}
}

java中队列Queue的使用的更多相关文章

  1. Java中的queue和deque对比详解

    队列(queue)简述 队列(queue)是一种常用的数据结构,可以将队列看做是一种特殊的线性表,该结构遵循的先进先出原则.Java中,LinkedList实现了Queue接口,因为LinkedLis ...

  2. java中并发Queue种类与各自API特点以及使用场景!

    一 先说下队列 队列是一种数据结构.它有两个基本操作:在队列尾部加入一个元素,和从队列头部移除一个元素(注意不要弄混队列的头部和尾部) 就是说,队列以一种先进先出的方式管理数据,如果你试图向一个 已经 ...

  3. Java 中队列同步器 AQS(AbstractQueuedSynchronizer)实现原理

    前言 在 Java 中通过锁来控制多个线程对共享资源的访问,使用 Java 编程语言开发的朋友都知道,可以通过 synchronized 关键字来实现锁的功能,它可以隐式的获取锁,也就是说我们使用该关 ...

  4. STL中队列queue的用法

    头文件:#include <queue> 建立一个队列queue < 类型 > q 加入一个新的元素q.push(a) 询问队首元素q.front() 弹出队首元素q.pop( ...

  5. Java 中队列的使用

    刚才看见群里的一个朋友在问队列的使用,确实在现实的写代码中非常少使用队列的,反正我是从来没使用过.仅仅是学数据结构的时候学过. 以下是我写的一个小样例,希望有不足之处请提出改正.O(∩_∩)O~ 看代 ...

  6. c++中队列queue和栈stack的基本操作

    1.queue 模板类的定义在<queue>头文件中. 定义queue 对象的示例代码如下:queue<int> q1;queue<double> q2; queu ...

  7. Java中队列

    定义 队的操作是在两端进行,一端只能进行插入操作(入队),称为队尾,一端只能进行删除操作(出队),称为队尾. 队列的运算规则是FIFO(first in first out). 队列的入队.出队操作分 ...

  8. JAVA中常见的阻塞队列详解

    在之前的线程池的介绍中我们看到了很多阻塞队列,这篇文章我们主要来说说阻塞队列的事. 阻塞队列也就是 BlockingQueue ,这个类是一个接 口,同时继承了 Queue 接口,这两个接口都是在JD ...

  9. Java 中的队列 Queue

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

随机推荐

  1. NYOJ201作业题

    作业题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 小白同学这学期有一门课程叫做<数值计算方法>,这是一门有效使用数字计算机求数学问题近似解的方法与过程, ...

  2. hdu_3003Pupu(快速幂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3003 Pupu Time Limit: 2000/1000 MS (Java/Others)    M ...

  3. Qt 共享库(动态链接库)和静态链接库的创建及调用

    前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...

  4. 30分钟学玩转RabbitMQ

    最近在学习RabbitMQ,在网上找了不少资料发现都特高端.动辄集群部署,分布式架构什么的,对于一个初学者实在不够友好.心想求人不如求自己,为什么不自己整理一套资料呢?于是<30分钟学玩转Rab ...

  5. SQLite学习手册(实例代码<一>)

    一.获取表的Schema信息:       1). 动态创建表.     2). 根据sqlite3提供的API,获取表字段的信息,如字段数量以及每个字段的类型.     3). 删除该表.     ...

  6. 用CSS实现“表格布局”

    当我们进行浮动布局时,会发现存在着非浮动元素与浮动元素的底部难以对齐的情况,这就是浮动布局的缺陷.因此,过去的前端工作者曾利用<table>以实现"表格布局".因为表格 ...

  7. Java中实例方法、类方法和构造方法

    类方法,有static修饰符,典型的主函数public static void main(String[] args){}实例方法,就是一般的方法构造方法,没有返回值(就是连void都没有),方法名与 ...

  8. WEB前端大神之路之基础篇

    CSS篇: 1.CSS权重: 不重复造轮子啦,直接传送门(CSS选择器的权重与优先规则) JavaScript篇: 1.this关键字: 它是一种引用(referent).指向的是当前上下文(cont ...

  9. python_14_生成器

    什么是生成器? -- 动态的生成有规律的列表和元组,查询多少才会生成多少数据,不需要时数据不存在 - 大到10几万数据,就省空间了 什么是列表生成式? -- [ handle_i_result for ...

  10. Linux指令--rm, rmdir

    rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有文件均保持不变.rm是一个危险的命令,使用的时 ...