ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

技术问答-10 java中的集合(5)-Queue

2021-04-13 20:51:50  阅读:114  来源: 互联网

标签:10 java 队列 元素 queue Queue add 线程 new


Queue

一、Queue是什么

Queue是一种队列结构集合,用来储存将要进行处理的元素,一般会以FIFO的方式排序元素,但这不是必须的。比如优先级队列就是一个例外,优先级队列是以元素的值来排序。但是无论怎么样,每个queue的实现都必须制定它的排序属性。queue通常不定义元素的equal和hashCode

二、Queue的实现

1. 非阻塞

  • LinkedList 实现了Queue和AbstractQueue

  • PriorityQueue
    PriorityQueue类 实质上维护了一个有序列表。加入到Queue中的元素根据他们天然排序(通过实现Comparable实现)或者根据传递给构造函数的Comparator实现来定位,它的增加操作不是原子操作,没有添加任何锁,所以它是线程不安全的。

  • ConcurrentLinkedQueue
    ConcurrentLinkedQueue是基于链接节点的、线程安全的队列,并发访问不需要同步,
    它是非阻塞队列,使用CAS非阻塞算法实现
    推荐看看
    1. 阻塞
    java.util.concurrent中加入了BlockingQueue接口和五个阻塞队列,它实质上就是一种带有一点扭曲的FIFO数据结构。不是立即从队列添加或者删除元素,线程操作阻塞,直到有空间或元素可用

  • ArrayBlockingQueue :一个由数组支持的有界队列

  • LinkedBlockingQueue:一个由链表节点支持的可选有界的队列(固定线程 使用的就是它)

  • PriorityBlockingQueue:一个由优先级堆支持的***优先级队列

  • DelayQueue: 一个由优先级堆的、基于时间的调度队列 (定时线程 使用的就是它)

  • SynchronousQueue:一个利用BlockingQueue接口的简单聚集机制(缓存线程 使用的就是它)

三、方法
返回方法说明
booleanadd(E)添加元素,如果队列已满,抛出IllegalStateException
booleanoffer(E)与add一样,add就是调用的offer方法
Eremove()移除并返回队列头部元素,如果队列为空则抛出NoSuchElementException
Eelement()返回队列头部元素,如果队列为空则抛出NoSuchElementException
Epoll()移除并返回队列头部元素,如果队列为空则返回null
Epeek()返回队列头部元素 如果队列为空返回null
voidput(E)添加一个元素 如果队列满了 则阻塞
Etake()移除并返回队列头部元素,如果队列为空 则阻塞
package along;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.DelayQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.PriorityBlockingQueue;import java.util.concurrent.SynchronousQueue;import java.util.concurrent.TimeUnit;import com.mysql.jdbc.TimeUtil;public class javaTest {public static void main(String[] args) { 
		//ArrayBlockingQueue 
		ArrayBlockingQueue<Integer> aq = new ArrayBlockingQueue<Integer>(10);for(int i=0;i<11;i++){//aq.add(i);}//java.lang.IllegalStateException: Queue full//LinkedBlockingQueue ***  有界 
		LinkedBlockingQueue<Integer> lq1 = new LinkedBlockingQueue<Integer>();
		LinkedBlockingQueue<Integer> lq2 = new LinkedBlockingQueue<Integer>(10);//PriorityBlockingQueue
		PriorityBlockingQueue<Integer> pq = new PriorityBlockingQueue<Integer>();
		pq.add(2);pq.add(8);pq.add(1);pq.add(22);
		Integer i=null;while((i = pq.poll()) != null){
			System.out.println(i);}//1 2 8 22 按顺序排列 
		
		DelayQueue<DelayedTest> dq = new DelayQueue<DelayedTest>();//这里传入的参数是毫秒 他会转换成秒 再加上当前系统时间
		DelayedTest d1 = new DelayedTest(1, "111111111111111111111", 10000);
		DelayedTest d2 = new DelayedTest(2, "222222222222222222222", 20000);
		DelayedTest d3 = new DelayedTest(3, "333333333333333333333", 30000);
		dq.add(d1);
		dq.add(d2);
		dq.add(d3);try{//			System.out.println(dq.take());//元素被添加到队列  10秒后输出//			System.out.println(dq.take());//元素被添加到队列  20秒后输出//			System.out.println(dq.take());//元素被添加到队列  30秒后输出}catch(Exception e){
			System.out.println("error");}//SynchronousQueue 这个东西很神奇  它的作用是如果想add一个元素进去 必须有take在等待 也就是如果生产想要push必须等待消费者的take
		SynchronousQueue<Integer> sq =new SynchronousQueue<>();//		sq.add(12);//没有线程take这里是没有办法加进去的new Thread(new Runnable() {public void run() {try{
					System.out.println("元素:"+sq.take());}catch(Exception e){
					e.printStackTrace();}}}).start();
	   //主线程等待2秒钟try {
			TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e1) {
			e1.printStackTrace();}new Thread(new Runnable() {public void run() {try{
					sq.add(1111);}catch(Exception e){
					e.printStackTrace();}}}).start();//但是用put不会报错 他会等着take操作  没有take他不会put成功try {
			sq.put(1212);} catch (InterruptedException e) {
			e.printStackTrace();} /**
	    * iterator() 永远返回空,因为里面没东西。 
	    * peek() 永远返回null。 
	    * put() 往queue放进去一个element以后就一直wait直到有其他thread进来把这个element取走。 
	    * offer() 往queue里放一个element后立即返回,如果碰巧这个element被另一个thread取走了,offer方法返回true,认为offer成功;否则返回false。 
	    * offer(2000, TimeUnit.SECONDS) 往queue里放一个element但是等待指定的时间后才返回,返回的逻辑和offer()方法一样。 
	    * take() 取出并且remove掉queue里的element(认为是在queue里的。。。),取不到东西他会一直等。 
	    * poll() 取出并且remove掉queue里的element(认为是在queue里的。。。),只有到碰巧另外一个线程正在往queue里offer数据或者put数据的时候,该方法才会取到东西。否则立即返回null。 
	    * poll(2000, TimeUnit.SECONDS) 等待指定的时间然后取出并且remove掉queue里的element,其实就是再等其他的thread来往里塞。 
	    * isEmpty()永远是true。 
	    * remainingCapacity() 永远是0。 
	    * remove()和removeAll() 永远是false。
	    */// SynchronousQueue 内部没有容量,但是由于一个插入操作总是对应一个移除操作,反过来同样需要满足。// 那么一个元素就不会再SynchronousQueue 里面长时间停留,一旦有了插入线程和移除线程,元素很快就从插入线程移交给移除线程。//也就是说这更像是一种信道(管道),资源从一个方向快速传递到另一方 向。//显然这是一种快速传递元素的方式,也就是说在这种情况下元素总是以最快的方式从插入着(生产者)传递给移除着(消费者),//这在多任务队列中是最快处理任务的方式。//在线程池里的一个典型应用是Executors.newCachedThreadPool()就使用了SynchronousQueue,//这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。}}

标签:10,java,队列,元素,queue,Queue,add,线程,new
来源: https://blog.51cto.com/u_12198094/2704039

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有