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. Codeforces Round #336 (Div. 2)【A.思维,暴力,B.字符串,暴搜,前缀和,C.暴力,D,区间dp,E,字符串,数学】

    A. Saitama Destroys Hotel time limit per test:1 second memory limit per test:256 megabytes input:sta ...

  2. RabbitMQ 使用demo

    1.新建一个控制台应用程序:如图 2.代码如下: using RabbitMQ.Client;using RabbitMQ.Client.Events;using System;using Syste ...

  3. C# delegate event func action 匿名方法 lambda表达式

    delegate event action func 匿名方法 lambda表达式 delegate类似c++的函数指针,但是是类型安全的,可以指向多个函数, public delegate void ...

  4. c++---天梯赛---N个数求和

    ★题目: ★难点:要求只能以有理数和分数去输出结果. ★分析:可以对输入的数据进行通分处理,随后把结果按格式输出. ★代码: #include<iostream> #include< ...

  5. myeclipse10不用打开myeclipse configuration center安装插件的方法

    我使用myeclipse10,网上找了一大堆的插件安装方法,全部都是要通过help->myeclipse configuration center进行安装 不用打开myeclipse  conf ...

  6. 20165206学习基础和C语言基础调查

    - 技能 我的一项可以拿的出手的技能是萨克斯.但不敢说有多厉害,更不敢说比大多数人更好,只能说是还可以.我学萨克斯有5年左右的时间吧,这5年里印象最深刻的还是前两年.前两年主要是基础训练.我从最基础的 ...

  7. system进程占用80端口

    服务器规划:apache分配80,iis分配其他端口 理论上,只需要把iis 默认站点的80端口改成其他端口就可以了,可是发现改了apache80端口还是用不了, cmd查了下,发现system进程占 ...

  8. 深入理解HashMap的扩容机制

    什么时候扩容: 网上总结的会有很多,但大多都总结的不够完整或者不够准确.大多数可能值说了满足我下面条件一的情况. 扩容必须满足两个条件: 1. 存放新值的时候当前已有元素的个数必须大于等于阈值 2. ...

  9. HotSpot 虚拟机的算法实现

  10. Java常用类--处理日期

    Date Date类在java.util包中.使用Date类的无参数构造方法创建的对象可以获取本地当前时间.一般来说,也只使用这个.因为date的很多方法都已经不推荐使用了,所以Date的功能大大的消 ...