百度
360搜索
搜狗搜索

java queue,java中的队列都有哪些,有什么区别详细介绍

本文目录一览: java中的“queue类”是什么,有什么作用?

java中的queue类是队列数据结构管理类。在它里边的元素可以按照添加它们的相同顺序被移除。\x0d\x0a队列通常(但并非一定)以 FIFO(先进先出)的方式排序各个元素。不过优先级队列和 LIFO 队列(或堆栈)例外,前者根据提供的比较器或元素的自然顺序对元素进行排序,后者按 LIFO(后进先出)的方式对元素进行排序。无论使用哪种排序方式,队列的头都是调用remove()或poll()所移除的元素。在 FIFO 队列中,所有的新元素都插入队列的末尾。其他种类的队列可能使用不同的元素放置规则。每个Queue实现必须指定其顺序属性。\x0d\x0a \x0d\x0aoffer 添加一个元素并返回true 如果队列已满,则返回false\x0d\x0apoll 移除并返问队列头部的元素 如果队列为空,则返回null\x0d\x0apeek 返回队列头部的元素 如果队列为空,则返回null\x0d\x0aput 添加一个元素 如果队列满,则阻塞\x0d\x0atake 移除并返回队列头部的元素 如果队列为空,则阻塞\x0d\x0aelement 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常\x0d\x0a\x0d\x0aadd 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常\x0d\x0aremove 移除并返回队列头部的元素 如果队列为空,则抛出一个\x0d\x0aNoSuchElementException异常\x0d\x0a\x0d\x0a注意:poll和peek方法出错进返回null。因此,向队列中插入null值是不合法的。\x0d\x0a \x0d\x0a还有带超时的offer和poll方法重载,例如,下面的调用:\x0d\x0aboolean success = q.offer(x,100,TimeUnit.MILLISECONDS);\x0d\x0a尝试在100毫秒内向队列尾部插入一个元素。如果成功,立即返回true;否则,当到达超时进,返回false。同样地,调用:\x0d\x0aObject head = q.poll(100, TimeUnit.MILLISECONDS);\x0d\x0a如果在100毫秒内成功地移除了队列头元素,则立即返回头元素;否则在到达超时时,返回null。\x0d\x0a阻塞操作有put和take。put方法在队列满时阻塞,take方法在队列空时阻塞。\x0d\x0a \x0d\x0aQueue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接 口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。

queue java 是怎么实现的

java中queue的使用
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接 口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。
队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就是说,队列以一种先进先出的方式管理数据,如果你试图向一个 已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具。工作者线程可 以定期地把中间结果存到阻塞队列中而其他工作者线线程把中间结果取出并在将来修改它们。队列会自动平衡负载。如果第一个线程集运行得比第二个慢,则第二个 线程集在等待结果时就会阻塞。如果第一个线程集运行得快,那么它将等待第二个线程集赶上来。下表显示了jdk1.5中的阻塞队列的操作:
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞
remove、element、offer 、poll、peek 其实是属于Queue接口。
阻塞队列的操作可以根据它们的响应方式分为以下三类:aad、removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时 抛出异常。当然,在多线程程序中,队列在任何时间都可能变成满的或空的,所以你可能想使用offer、poll、peek方法。这些方法在无法完成任务时 只是给出一个出错示而不会抛出异常。
注意:poll和peek方法出错进返回null。因此,向队列中插入null值是不合法的。
还有带超时的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中关于如何实现多线程消息队列的实例(java多线程通信)

java中的消息队列
消息队列是线程间通讯的手段:
importjava.util.*
publicclassMsgQueue{
privateVectorqueue=null;
publicMsgQueue(){
queue=newVector();
}
publicvoidsend(Objecto)
{
queue.addElement(o);
}
publicObjectrecv()
{
if(queue.size()==0)
returnnull;
Objecto=queue.();
queue.(0);//orqueue[0]=nullcanalsowork
returno;
}
}
因为java中是lockedbyobject的所以添加就可以用于线程同步锁定对象
可以作为多线程处理多任务的存放task的队列。他的client包括封装好的task类以及thread类
Java的多线程-线程间的通信2009-08-2521:58
1.线程的几种状态
线程有四种状态,任何一个线程肯定处于这四种状态中的一种:
1)产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。
2)可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。
3)死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。
4)停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。
2.classThread下的常用函数函数
2.1suspend()、resume()
1)通过suspend()函数,可使线程进入停滞状态。通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回可执行状态。
2)当调用suspend()函数后,线程不会释放它的“锁标志”。
例11:
classextendsThread{
publicstaticintshareVar=0;
public(Stringname){
super(name);
}
publicvoidrun(){
if(shareVar==0){
for(inti=0;i<5;i){
shareVar;
if(shareVar==5){
this.suspend();//(1)
}}}
else{
System.out.print(Thread.().getName());
System.out.println("shareVar="shareVar);
this.resume();//(2)
}}
}
publicclassTestThread{
publicstaticvoidmain(String[]args){
t1=new("t1");
t2=new("t2");
t1.start();//(5)
//t1.start();//(3)
t2.start();//(4)
}}

到底什么是消息队列?Java中如何实现消息队列

消息队列,顾名思义 首先是个队列。
队列的操作有入队和出队
也就是有一个程序在产生内容然后入队(生产者)
另一个程序读取内容,内容出队(消费者)
这是最最基本的概念。
java中的消息队列
消息队列是线程间通讯的手段:
import java.util.*public class MsgQueue{private Vector queue = null;public MsgQueue(){queue = new Vector();}public synchronized void send(Object o){queue.addElement(o);}public synchronized Object recv(){if(queue.size()==0)return null;Object o = queue.firstElement();queue.removeElementAt(0);//or queue[0] = null can also workreturn o;}}因为java中是locked by object的所以添加synchronized 就可以用于线程同步锁定对象
可以作为多线程处理多任务的存放task的队列。他的client包括封装好的task类以及thread类
所谓队列,就是按照队首先出的规则建立的数据结构,消息队列就是根据消息到来后按照一定的规则进行排序,但一定是队首的消息先得到应答的队列。(建议学下数据结构)

java中创建队列Queue的问题

Queue这是个接口,你要new一个它的实现类;例如:
Queue

queue = new ArrayBlockingQueue

(100);

因为queue是接口,不能new 接口,应该new接口实现类,你看jdk文档,搜索queue,如图:

看见下面有一大堆实现queue的类,选一个就行,针对队列的,你可以选LinkedBlockingQueue,AbstrctQueue,ArrayDeque

java中的队列都有哪些,有什么区别

阻塞队列、普通队列,非阻塞队列。
阻塞队列与普通队列的而区别在于,当队列是空时,从队列中获取元素的操作会被阻塞,或则当队列是满的时,往队列中增加元素会被阻塞,试图从空的队列中取元素的线程或从满的队列中添加元素的线程同样会被阻塞。
队列的两个基本操作是inserting(插入)一个数据项,即把一个数据项放入队尾,另一个是removing(移除)一个数据项,即移除队头的数据项。这类似于电影爱好者排队买票时先排到队尾,然后到达队头买票后离开队列。
栈中的插入和移除数据项方法的命名是很标准,称为push和pop。队列的方法至今没有标准化的命名。“插入”可以称为put、add或enque,而“删除”可以叫delete、get或deque。插入数据项的队尾,也可以叫作back、tail或end。而移除数据项的队头,也可以叫head。下面将使用insert、remove、front和rear。
插入将值插入队尾,同时队尾箭头增加一,指向新的数据项。
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列.
从5.0开始,JDK在java.util.concurrent包里提供了阻塞队列的官方实现。尽管JDK中已经包含了阻塞队列的官方实现,但是熟悉其背后的原理还是很有帮助的。一下是阻塞队列的实现:
public class BlockingQueue {
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
if(this.queue.size() == 0) {
notifyAll();
}
this.queue.add(item);
}
public synchronized Object dequeue()
throws InterruptedException{
while(this.queue.size() == 0){
wait();
}
if(this.queue.size() == this.limit){
notifyAll();
}
return this.queue.remove(0);
}
}

Java多线程(五)之BlockingQueue深入分析

   一 概述
  BlockingQueue作为线程容器 可以为线程同步提供有力的保障
   二 BlockingQueue定义的常用方法
   BlockingQueue定义的常用方法如下
  抛出异常 特殊值 阻塞 超时

  插入 add(e) offer(e) put(e) offer(e time unit)
  移除 remove() poll() take() poll(time unit)
  检查 element() peek() 不可用 不可用
   )add(anObject) 把anObject加到BlockingQueue里 即如果BlockingQueue可以容纳 则返回true 否则招聘异常
   )offer(anObject) 表示如果可能的话 将anObject加到BlockingQueue里 即如果BlockingQueue可以容纳 则返回true 否则返回false
   )put(anObject) 把anObject加到BlockingQueue里 如果BlockQueue没有空间 则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续
   )poll(time) 取走BlockingQueue里排在首位的对象 若不能立即取出 则可以等time参数规定的时间 取不到时返回null
   )take() 取走BlockingQueue里排在首位的对象 若BlockingQueue为空 阻断进入等待状态直到Blocking有新的对象被加入为止
  其中 BlockingQueue 不接受null 元素 试图add put 或offer 一个null 元素时 某些实现会抛出NullPointerException null 被用作指示poll 操作失败的警戒值
   三 BlockingQueue的几个注意点
  【 】BlockingQueue 可以是限定容量的 它在任意给定时间都可以有一个remainingCapacity 超出此容量 便无法无阻塞地put 附加元素 没有任何内部容量约束的BlockingQueue 总是报告Integer MAX_VALUE 的剩余容量
  【 】BlockingQueue 实现主要用于生产者 使用者队列 但它另外还支持Collection 接口 因此 举例来说 使用remove(x) 从队列中移除任意一个元素是有可能的 然而 这种操作通常不 会有效执行 只能有计划地偶尔使用 比如在取消排队信息时
  【 】BlockingQueue 实现是线程安全的 所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的 然而 大量的 Collection 操作(addAll containsAll retainAll 和removeAll)没有 必要自动执行 除非在实现中特别说明 因此 举例来说 在只添加了c 中的一些元素后 addAll(c) 有可能失败(抛出一个异常)
  【 】BlockingQueue 实质上不 支持使用任何一种 close 或 shutdown 操作来指示不再添加任何项 这种功能的需求和使用有依赖于实现的倾向 例如 一种常用的策略是 对于生产者 插入特殊的end of stream 或 poison 对象 并根据使用者获取这些对象的时间来对它们进行解释
   四 简要概述BlockingQueue常用的四个实现类
  
   )ArrayBlockingQueue:规定大小的BlockingQueue 其构造函数必须带一个int参数来指明其大小 其所含的对象是以FIFO(先入先出)顺序排序的
  
   )LinkedBlockingQueue:大小不定的BlockingQueue 若其构造函数带一个规定大小的参数 生成的BlockingQueue有大小限制 若不带大小参数 所生成的BlockingQueue的大小由Integer MAX_VALUE来决定 其所含的对象是以FIFO(先入先出)顺序排序的
   )PriorityBlockingQueue:类似于LinkedBlockQueue 但其所含对象的排序不是FIFO 而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序
   )SynchronousQueue:特殊的BlockingQueue 对其的操作必须是放和取交替完成的
  其中LinkedBlockingQueue和ArrayBlockingQueue比较起来 它们背后所用的数据结构不一样 导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue 但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue
   五 具体BlockingQueue的实现类的内部细节
   有耐心的同学请看具体实现类细节
   ArrayBlockingQueue
  ArrayBlockingQueue是一个由数组支持的有界阻塞队列 此队列按 FIFO(先进先出)原则对元素进行排序 队列的头部 是在队列中存在时间最长的元素 队列的尾部 是在队列中存在时间最短的元素 新元素插入到队列的尾部 队列检索操作则是从队列头部开始获得元素
  这是一个典型的 有界缓存区 固定大小的数组在其中保持生产者插入的元素和使用者提取的元素 一旦创建了这样的缓存区 就不能再增加其容量 试图向已满队列中放入元素会导致放入操作受阻塞 试图从空队列中检索元素将导致类似阻塞
  ArrayBlockingQueue创建的时候需要指定容量capacity(可以存储的最大的元素个数 因为它不会自动扩容)以及是否为公平锁(fair参数)
  在创建ArrayBlockingQueue的时候默认创建的是非公平锁 不过我们可以在它的构造函数里指定 这里调用ReentrantLock的构造函数创建锁的时候 调用了
  public ReentrantLock(boolean fair) {
  sync = (fair)? new FairSync() : new NonfairSync()
  }
  FairSync/ NonfairSync是ReentrantLock的内部类
  线程按顺序请求获得公平锁 而一个非公平锁可以闯入 且当它尚未进入等待队列 就会和等待队列head结点的线程发生竞争 如果锁的状态可用 请求非公平锁的线程可在等待队列中向前跳跃 获得该锁 内部锁synchronized没有提供确定的公平性保证
  分三点来讲这个类
   添加新元素的方法 add/put/offer
   该类的几个实例变量 takeIndex/putIndex/count/
   Condition实现
   添加新元素的方法 add/put/offer
  首先 谈到添加元素的方法 首先得分析以下该类同步机制中用到的锁
   Java代码
  [java]
  lock = new ReentrantLock(fair)
  notEmpty = lock newCondition() //Condition Variable
  notFull = lock newCondition() //Condition Variable
  这三个都是该类的实例变量 只有一个锁lock 然后lock实例化出两个Condition notEmpty/noFull分别用来协调多线程的读写操作
  Java代码
  [java]
  public boolean offer(E e) {
  if (e == null) throw new NullPointerException()
  final ReentrantLock lock = this lock;//每个对象对应一个显示的锁
  lock lock() //请求锁直到获得锁(不可以被interrupte)
  try {
  if (count == items length)//如果队列已经满了
  return false;
  else {
  insert(e)
  return true;
  }
  } finally {
  lock unlock() //
  }
  }
  看insert方法
  private void insert(E x) {
  items[putIndex] = x;
  //增加全局index的值
  /*
  Inc方法体内部
  final int inc(int i) {
  return (++i == items length)? : i;
  }
  这里可以看出ArrayBlockingQueue采用从前到后向内部数组插入的方式插入新元素的 如果插完了 putIndex可能重新变为 (在已经执行了移除操作的前提下 否则在之前的判断中队列为满)
  */
  putIndex = inc(putIndex)
  ++count;
  notEmpty signal() //wake up one waiting thread
  }
   Java代码
  [java]
  public void put(E e) throws InterruptedException {
  if (e == null) throw new NullPointerException()
  final E[] items = ems;
  final ReentrantLock lock = this lock;
  lock lockInterruptibly() //请求锁直到得到锁或者变为interrupted
  try {
  try {
  while (count == items length)//如果满了 当前线程进入noFull对应的等waiting状态
  notFull await()
  } catch (InterruptedException ie) {
  notFull signal() // propagate to non interrupted thread
  throw ie;
  }
  insert(e)
  } finally {
  lock unlock()
  }
  }
   Java代码
  [java]
  public boolean offer(E e long timeout TimeUnit unit)
  throws InterruptedException {
  if (e == null) throw new NullPointerException()
  long nanos = unit toNanos(timeout)
  final ReentrantLock lock = this lock;
  lock lockInterruptibly()
  try {
  for ( ) {
  if (count != items length) {
  insert(e)
  return true;
  }
  if (nanos <= )
  return false;
  try {
  //如果没有被 signal/interruptes 需要等待nanos时间才返回
  nanos = notFull awaitNanos(nanos)
  } catch (InterruptedException ie) {
  notFull signal() // propagate to non interrupted thread
  throw ie;
  }
  }
  } finally {
  lock unlock()
  }
  }
   Java代码
  [java]
  public boolean add(E e) {
  return super add(e)
  }
  父类
  public boolean add(E e) {
  if (offer(e))
  return true;
  else
  throw new IllegalStateException( Queue full )
  }
   该类的几个实例变量 takeIndex/putIndex/count
   Java代码
  [java]
  用三个数字来维护这个队列中的数据变更
  /** items index for next take poll or remove */
  private int takeIndex;
  /** items index for next put offer or add */
  private int putIndex;
  /** Number of items in the queue */
  private int count;
  提取元素的三个方法take/poll/remove内部都调用了这个方法
  Java代码
  [java]
  private E extract() {
  final E[] items = ems;
  E x = items[takeIndex];
  items[takeIndex] = null;//移除已经被提取出的元素
  takeIndex = inc(takeIndex) //策略和添加元素时相同
   count;
  notFull signal() //提醒其他在notFull这个Condition上waiting的线程可以尝试工作了
  return x;
  }
  从这个方法里可见 tabkeIndex维护一个可以提取/移除元素的索引位置 因为takeIndex是从 递增的 所以这个类是FIFO队列
  putIndex维护一个可以插入的元素的位置索引
  count显然是维护队列中已经存在的元素总数
   Condition实现
  Condition现在的实现只有ncurrent locks AbstractQueueSynchoronizer内部的ConditionObject 并且通过ReentranLock的newCondition()方法暴露出来 这是因为Condition的await()/sinal()一般在lock lock()与lock unlock()之间执行 当执行condition await()方法时 它会首先释放掉本线程持有的锁 然后自己进入等待队列 直到sinal() 唤醒后又会重新试图去拿到锁 拿到后执行await()下的代码 其中释放当前锁和得到当前锁都需要ReentranLock的tryAcquire(int arg)方法来判定 并且享受ReentranLock的重进入特性
   Java代码
  [java]
  public final void await() throws InterruptedException {
  if (Thread interrupted())
  throw new InterruptedException()
  //加一个新的condition等待节点
  Node node = addConditionWaiter()
  //释放自己的锁
  int savedState = fullyRelease(node)
  int interruptMode = ;
  while (!isOnSyncQueue(node)) {
  //如果当前线程 等待状态时CONDITION park住当前线程 等待condition的signal来解除
  LockSupport park(this)
  if ((interruptMode = checkInterruptWhileWaiting(node)) != )
  break;
  }
  if (acquireQueued(node savedState) && interruptMode != THROW_IE)
  interruptMode = REINTERRUPT;
  if (node nextWaiter != null)
  unlinkCancelledWaiters()
  if (interruptMode != )
  reportInterruptAfterWait(interruptMode)
  }
   SynchronousQueue
  一种阻塞队列 其中每个 put 必须等待一个 take 反之亦然 同步队列没有任何内部容量 甚至连一个队列的容量都没有 不能在同步队列上进行 peek 因为仅在试图要取得元素时 该元素才存在 除非另一个线程试图移除某个元素 否则也不能(使用任何方法)添加元素 也不能迭代队列 因为其中没有元素可用于迭代 队列的头 是尝试添加到队列中的首个已排队线程元素 如果没有已排队线程 则不添加元素并且头为 null 对于其他Collection 方法(例如 contains) SynchronousQueue 作为一个空集合 此队列不允许 null 元素
  同步队列类似于 CSP 和 Ada 中使用的 rendezvous 信道 它非常适合于传递性设计 在这种设计中 在一个线程中运行的对象要将某些信息 事件或任务传递给在另一个线程中运行的对象 它就必须与该对象同步
  对于正在等待的生产者和使用者线程而言 此类支持可选的公平排序策略 默认情况下不保证这种排序 但是 使用公平设置为 true 所构造的队列可保证线程以 FIFO 的顺序进行访问 公平通常会降低吞吐量 但是可以减小可变性并避免得不到服务
   LinkedBlockingQueue
  一个基于已链接节点的 范围任意的 blocking queue 此队列按 FIFO(先进先出)排序元素 队列的头部 是在队列中时间最长的元素 队列的尾部 是在队列中时间最短的元素 新元素插入到队列的尾部 并且队列检索操作会获得位于队列头部的元素 链接队列的吞吐量通常要高于基于数组的队列 但是在大多数并发应用程序中 其可预知的性能要低
  单向链表结构的队列 如果不指定容量默认为Integer MAX_VALUE 通过putLock和takeLock两个锁进行同步 两个锁分别实例化notFull和notEmpty两个Condtion 用来协调多线程的存取动作 其中某些方法(如remove toArray toString clear等)的同步需要同时获得这两个锁 并且总是先putLock lock紧接着takeLock lock(在同一方法fullyLock中) 这样的顺序是为了避免可能出现的死锁情况(我也想不明白为什么会是这样?)
   PriorityBlockingQueue
  一个无界的阻塞队列 它使用与类 PriorityQueue 相同的顺序规则 并且提供了阻塞检索的操作 虽然此队列逻辑上是无界的 但是由于资源被耗尽 所以试图执行添加操作可能会失败(导致 OutOfMemoryError) 此类不允许使用 null 元素 依赖自然顺序的优先级队列也不允许插入不可比较的对象(因为这样做会抛出ClassCastException)
   看它的三个属性 就基本能看懂这个类了
   Java代码
  [java]
  private final PriorityQueue q;
  private final ReentrantLock lock = new ReentrantLock(true)
  private final Condition notEmpty = lock newCondition()
  lock说明本类使用一个lock来同步读写等操作
  notEmpty协调队列是否有新元素提供 而队列满了以后会调用PriorityQueue的grow方法来扩容
   DelayQueue
  Delayed 元素的一个无界阻塞队列 只有在延迟期满时才能从中提取元素 该队列的头部 是延迟期满后保存时间最长的 Delayed 元素 如果延迟都还没有期满 则队列没有头部 并且 poll 将返回 null 当一个元素的getDelay(TimeUnit NANOSECONDS) 方法返回一个小于或等于零的值时 则出现期满 此队列不允许使用 null 元素
  Delayed接口继承自Comparable 我们插入的E元素都要实现这个接口
  DelayQueue的设计目的间API文档
  An unbounded blocking queue of Delayed elements in which an element can only be taken when its delay has expired The head of the queue is that Delayed element whose delay expired furthest in the past If no delay has expired there is no head and poll will returnnull Expiration occurs when an element s getDelay(TimeUnit NANOSECONDS) method returns a value less than or equal to zero Even though unexpired elements cannot be removed using take or poll they are otherwise treated as normal elements For example the size method returns the count of both expired and unexpired elements This queue does not permit null elements
  因为DelayQueue构造函数了里限定死不允许传入parator(之前的PriorityBlockingQueue中没有限定死) 即只能在pare方法里定义优先级的比较规则 再看上面这段英文 The head of the queue is that Delayed element whose delay expired furthest in the past 说明pare方法实现的时候要保证最先加入的元素最早结束延时 而 Expiration occurs when an element s getDelay(TimeUnit NANOSECONDS) method returns a value less than or equal to zero 说明getDelay方法的实现必须保证延时到了返回的值变为<= 的int
  上面这段英文中 还说明了 在poll/take的时候 队列中元素会判定这个elment有没有达到超时时间 如果没有达到 poll返回null 而take进入等待状态 但是 除了这两个方法 队列中的元素会被当做正常的元素来对待 例如 size方法返回所有元素的数量 而不管它们有没有达到超时时间 而协调的Condition available只对take和poll是有意义的
  另外需要补充的是 在ScheduledThreadPoolExecutor中工作队列类型是它的内部类DelayedWorkQueue 而DelayedWorkQueue的Task容器是DelayQueue类型 而ScheduledFutureTask作为Delay的实现类作为Runnable的封装后的Task类 也就是说ScheduledThreadPoolExecutor是通过DelayQueue优先级判定规则来执行任务的
   BlockingDque+LinkedBlockingQueue
lishixinzhi/Article/program/Java/gj/201311/27544

阅读更多 >>>  怎么在linux安装hadoop

java阻塞队列 线程同步合作

  Queue接口与List Set同一级别 都是继承了Collection接口 LinkedList实现了Queue接口 Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时 就完全只能访问Queue接口所定义的方法了 而不能直接访问 LinkedList的非Queue的方法) 以使得只有恰当的方法才可以使用 BlockingQueue 继承了Queue接口
  队列是一种数据结构.它有两个基本操作 在队列尾部加人一个元素 和从队列头部移除一个元素就是说 队列以一种先进先出的方式管理数据 如果你试图向一个已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索 将导致线程阻塞.在多线程进行合作时 阻塞队列是很有用的工具 工作者线程可以定期地把中间结果存到阻塞队列中而其他工作者线线程把中间结果取出并在将来修改它们 队列会自动平衡负载 如果第一个线程集运行得比第二个慢 则第二个线程集在等待结果时就会阻塞 如果第一个线程集运行得快 那么它将等待第二个线程集赶上来 下表显示了jdk 中的阻塞队列的操作
  add 增加一个元索 如果队列已满 则抛出一个IIIegaISlabEepeplian异常
  remove 移除并返回队列头部的元素 如果队列为空 则抛出一个NoSuchElementException异常
  element 返回队列头部的元素 如果队列为空 则抛出一个NoSuchElementException异常

  offer 添加一个元素并返回true 如果队列已满 则返回false
  poll 移除并返问队列头部的元素 如果队列为空 则返回null
  peek 返回队列头部的元素 如果队列为空 则返回null
  put 添加一个元素 如果队列满 则阻塞
  take 移除并返回队列头部的元素 如果队列为空 则阻塞
  remove element offer poll peek 其实是属于Queue接口
  阻塞队列的操作可以根据它们的响应方式分为以下三类 aad removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时抛出异常 当然 在多线程程序中 队列在任何时间都可能变成满的或空的 所以你可能想使用offer poll peek方法 这些方法在无法完成任务时只是给出一个出错示而不会抛出异常
  注意 poll和peek方法出错进返回null 因此 向队列中插入null值是不合法的
  还有带超时的offer和poll方法变种 例如 下面的调用
  boolean success = q offer(x TimeUnit MILLISECONDS);
  尝试在 毫秒内向队列尾部插入一个元素 如果成功 立即返回true 否则 当到达超时进 返回false 同样地 调用
  Object head = q poll( TimeUnit MILLISECONDS);
  如果在 毫秒内成功地移除了队列头元素 则立即返回头元素 否则在到达超时时 返回null
  最后 我们有阻塞操作put和take put方法在队列满时阻塞 take方法在队列空时阻塞
  ncurrent包提供了阻塞队列的 个变种 默认情况下 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

{

  long getDelay(TimeUnit unit);

  }

  public interface Delayed extends Comparable

{

  long getDelay(TimeUnit unit);

  }

  放入DelayQueue的元素还将要实现pareTo方法 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/jdk /src): );

  String directory = in nextLine();

  System out print( Enter keyword (e g volatile): );

  String keyword = in nextLine();

  final int FILE_QUEUE_SIZE = ;// 阻塞队列大小

  final int SEARCH_THREADS = ;// 关键字搜索线程个数

  // 基于ArrayBlockingQueue的阻塞队列

  BlockingQueue

阅读更多 >>>  java web是什么意思,你好,我是java新手,向你请教一个问题,请问web端和ap端是什么意思?

queue = new ArrayBlockingQueue

(

  FILE_QUEUE_SIZE);

  //只启动一个线程来搜索目录

  FileEnumerationTask enumerator = new FileEnumerationTask(queue

  new File(directory));

  new Thread(enumerator) start();

  //启动 个线程用来在文件中搜索指定的关键字

  for (int i = ; i <= SEARCH_THREADS; i++)

  new Thread(new SearchTask(queue keyword)) start();

  }

  }

  class FileEnumerationTask implements Runnable {

  //哑元文件对象 放在阻塞队列最后 用来标示文件已被遍历完

  public static File DUMMY = new File( );

  private BlockingQueue

queue;

  private File startingDirectory;

  public FileEnumerationTask(BlockingQueue

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

queue;

  private String keyword;

  public SearchTask(BlockingQueue

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 = ;

  while (in hasNextLine()) {

  lineNumber++;

  String line = in nextLine();

  if (ntains(keyword))

  System out printf( %s:%d:%s%n file getPath() lineNumber

  line);

  }

  in close();

  }

lishixinzhi/Article/program/Java/hx/201311/26657

java中Queue为什么不能实例化?

Queue是一个接口,下有ArrayBlockingQueue、ArrayBlockingQueue等等具体实现类。new当然不能new接口(除非想自己实现)。可以查API看看有哪些实现类,或者在eclipse里F4看继承结构。
接口不能实例化,意思就是说不能new一个对象。
Queue是一个接口,如果要想实现可以实现它的实现类。如图红色部分。

关于JAVA队列的申明

ConcurrentLinkedQueue 并发链接队列
LinkedBlockingQueue 链接阻塞队列
我这里有一个测试代码,其中可以很明显的看到其中区别
public class QueueTest {
public static void main(String[] args) {
BlockingQueue

blockQueue = new LinkedBlockingQueue

();//new SynchronousQueue

()

class QueuePuter implements Runnable{

private BlockingQueue queue;

public QueuePuter(BlockingQueue queue) {

this.queue = queue;

}

public void run() {

try {

for(int i=0;i<10;i++){

queue.put("Item "+i);

System.out.println("Put >>> Item "+i);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

阅读更多 >>>  java工作太难找了,我是今年刚刚大学毕业的学生,在广州这边找java开发方向的工作差不多两个多月了,是不是在这边很难找啊?

class QueueTaker implements Runnable{

private BlockingQueue queue;

public QueueTaker(BlockingQueue queue) {

this.queue = queue;

}

public void run() {

try {

Object obj = null;

while((obj = queue.take())!=null){

System.out.println("Take >>> "+obj);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

new Thread(new QueueTaker(blockQueue)).start();

//如果是 SynchronousQueue 把这行注释掉 程序会阻塞,说明如果没有线程执行take()操作则所有线程的put()操作都会被阻塞。

//如果是 LinkedBlockingQueue 把这行注释掉 程序会正常退出,说明就算没有take()操作的线程,所有线程的put()操作也可以把所有数据写入管道,而且管道容量可以不限。

new Thread(new QueuePuter(blockQueue)).start();

//如果是 SynchronousQueue 把这行注释掉 程序会阻塞, 说明如果没有线程执行put()操作则所有线程take()都会被阻塞。而且take()操作执行了几次,put()操作也只能执行几次,说明管道是没有容量的,同时只能操作一个元素。

//如果是 LinkedBlockingQueue 把这行注释掉 程序会阻塞, 说明如果管道是空的并且没有线程执行put()操作则所有线程take()都会被阻塞。

}

}

网站数据信息

"java queue,java中的队列都有哪些,有什么区别"浏览人数已经达到25次,如你需要查询该站的相关权重信息,可以点击进入"Chinaz数据" 查询。更多网站价值评估因素如:java queue,java中的队列都有哪些,有什么区别的访问速度、搜索引擎收录以及索引量、用户体验等。 要评估一个站的价值,最主要还是需要根据您自身的需求,如网站IP、PV、跳出率等!