转载自 https://blog.csdn.net/u012881904/article/details/51491736

阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列.

1.ArrayDeque, (数组双端队列) 
2.PriorityQueue, (优先级队列) 
3.ConcurrentLinkedQueue, (基于链表的并发队列) 
4.DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口) 
5.ArrayBlockingQueue, (基于数组的并发阻塞队列) 
6.LinkedBlockingQueue, (基于链表的FIFO阻塞队列) 
7.LinkedBlockingDeque, (基于链表的FIFO双端阻塞队列) 
8.PriorityBlockingQueue, (带优先级的无界阻塞队列) 
9.SynchronousQueue (并发同步阻塞队列)

阻塞队列和生产者-消费者模式

阻塞队列(Blocking queue)提供了可阻塞的put和take方法,它们与可定时的offer和poll是等价的。如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。Queue的长度可以有限,也可以无限;无限的Queue永远不会充满,所以它的put方法永远不会阻塞。

阻塞队列支持生产者-消费者设计模式。一个生产者-消费者设计分离了“生产产品”和“消费产品”。该模式不会发现一个工作便立即处理,而是把工作置于一个任务(“to do”)清单中,以备后期处理。生产者-消费者模式简化了开发,因为它解除了生产者和消费者之间相互依赖的代码。生产者和消费者以不同的或者变化的速度生产和消费数据,生产者-消费者模式将这些活动解耦,因而简化了工作负荷的管理。

生产者-消费者设计是围绕阻塞队列展开的,生产者把数据放入队列,并使数据可用,当消费者为适当的行为做准备时会从队列中获取数据。生产者不需要知道消费者的省份或者数量,甚至根本没有消费者—它们只负责把数据放入队列。类似地,消费者也不需要知道生产者是谁,以及是谁给它们安排的工作。BlockingQueue可以使用任意数量的生产者和消费者,从而简化了生产者-消费者设计的实现。最常见的生产者-消费者设计是将线程池与工作队列相结合。

阻塞队列简化了消费者的编码,因为take会保持阻塞直到可用数据出现。如果生产者不能足够快地产生工作,让消费者忙碌起来,那么消费者只能一直等待,直到有工作可做。同时,put方法的阻塞特性也大大地简化了生产者的编码;如果使用一个有界队列,那么当队列充满的时候,生产者就会阻塞,暂不能生成更多的工作,从而给消费者时间来赶进进度。

有界队列是强大的资源管理工具,用来建立可靠的应用程序:它们遏制那些可以产生过多工作量、具有威胁的活动,从而让你的程序在面对超负荷工作时更加健壮。

虽然生产者-消费者模式可以把生产者和消费者的代码相互解耦合,但是它们的行为还是间接地通过共享队列耦合在一起了

类库中包含一些BlockingQueue的实现,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO队列,与 LinkedList和ArrayList相似,但是却拥有比同步List更好的并发性能。PriorityBlockingQueue是一个按优先级顺序排序的队列,当你不希望按照FIFO的属性处理元素时,这个PriorityBolckingQueue是非常有用的。正如其他排序的容器一样,PriorityBlockingQueue可以比较元素本身的自然顺序(如果它们实现了Comparable),也可以使用一个 Comparator进行排序。

最后一个BlockingQueue的实现是SynchronousQueue,它根本上不是一个真正的队列,因为它不会为队列元素维护任何存储空间。不过,它维护一个排队的线程清单,这些线程等待把元素加入(enqueue)队列或者移出(dequeue)队列。因为SynchronousQueue没有存储能力,所以除非另一个线程已经准备好参与移交工作,否则put和take会一直阻止。SynchronousQueue这类队列只有在消费者充足的时候比较合适,它们总能为下一个任务作好准备。

非阻塞算法

基于锁的算法会带来一些活跃度失败的风险。如果线程在持有锁的时候因为阻塞I/O,页面错误,或其他原因发生延迟,很可能所有的线程都不能前进了。 
一个线程的失败或挂起不应该影响其他线程的失败或挂起,这样的算法成为非阻塞(nonblocking)算法;如果算法的每一个步骤中都有一些线程能够继续执行,那么这样的算法称为锁自由(lock-free)算法。在线程间使用CAS进行协调,这样的算法如果能构建正确的话,它既是非阻塞的,又是锁自由的。非竞争的CAS总是能够成功,如果多个线程以一个CAS竞争,总会有一个胜出并前进。非阻塞算法堆死锁和优先级倒置有“免疫性”(但它们可能会出现饥饿和活锁,因为它们允许重进入)。

非阻塞算法通过使用低层次的并发原语,比如比较交换,取代了锁。原子变量类向用户提供了这些底层级原语,也能够当做“更佳的volatile变量”使用,同时提供了整数类和对象引用的原子化更新操作。

java 中 阻塞队列 非阻塞队列 和普通队列的区别相关推荐

  1. Java中的NIO非阻塞编程

    在JDK1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞API.对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端应用,往往需要一个更为 ...

  2. Java中如何使用非阻塞异步编程——CompletableFuture

    分享一波:程序员赚外快-必看的巅峰干货 对于Node开发者来说,非阻塞异步编程是他们引以为傲的地方.而在JDK8中,也引入了非阻塞异步编程的概念.所谓非阻塞异步编程,就是一种不需要等待返回结果的多线程 ...

  3. Java多线程学习二十五:阻塞和非阻塞队列的并发安全原理||如何选择适合自己的阻塞队列?

    阻塞和非阻塞队列的并发安全原理. 之前我们探究了常见的阻塞队列的特点,以 ArrayBlockingQueue 为例, 首先分析 BlockingQueue 即阻塞队列的线程安全原理,然后再看看它的兄 ...

  4. 阻塞和非阻塞队列下两种生产者消费者实现

    队列可分为两种,一种是阻塞队列,一种是非阻塞队列. 阻塞队列和非阻塞队列的区别:阻塞队列可以阻塞,非阻塞队列不能阻塞,只能使用队列wait(),notify()进行队列消息传送.而阻塞队列当队列里面没 ...

  5. JAVA 中IO总结 之前篇阻塞、非阻塞

    最近总结JAVA中的IO,遇到了有关阻塞.非阻塞.同步.异步的概念,之前也做个内核有关开发,今天温故而知新. Linux支持同步IO,也支持异步IO,因此分为同步阻塞.同步非阻塞,异步阻塞,异步非阻塞 ...

  6. Java 理论与实践: 非阻塞算法简介——看吧,没有锁定!(转载)

    简介: Java™ 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能,java.util.concurrent 包充分地利用了这个功能.非阻塞算法属于并发算法,它们可以安全地派生它们的线程, ...

  7. Java网络编程——11.非阻塞I/O

    2019独角兽企业重金招聘Python工程师标准>>> 要允许CPU速度高于网络,传统的Java解决方案是缓冲和多线程.对于相对简单的服务器和客户端,如果不需要非常高的性能,这种方法 ...

  8. Java 理论与实践: 非阻塞算法简介

    在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情.Java 语言中主要的同步手段就是 synchronized 关键字(也称为内在锁),它强制实行互斥,确 ...

  9. Java 理论与实践: 非阻塞算法简介--转载

    在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情.Java 语言中主要的同步手段就是synchronized 关键字(也称为内在锁),它强制实行互斥,确保 ...

  10. Linux 设备驱动中的 I/O模型(一)—— 阻塞和非阻塞I/O

    在前面学习网络编程时,曾经学过I/O模型 Linux 系统应用编程--网络编程(I/O模型),下面学习一下I/O模型在设备驱动中的应用. 回顾一下在Unix/Linux下共有五种I/O模型,分别是: ...

最新文章

  1. leetcode 74 java_【LeetCode】74. Search a 2D Matrix
  2. Linux --Solr 安装/配置
  3. 推荐一个Android Studio很实用的插件android-butterknife-zelezny
  4. Platforms/iPhoneSimulator.platform/Developer/usr/bin/g++-4.2 failed with exit code 1问题总结及解决方案...
  5. 我的第五个网页制作:pre、html转义、abbr标签的使用
  6. 注解_案例_简单的测试框架
  7. GT sport赛道详解 - Dragon Trail | 龙之径
  8. 【NOIP2016提高A组五校联考2】running
  9. linux crsctl start crs开机自动启动,CRS无法启动,运行crsctl start crs无响应
  10. c ++ 继承_了解C ++中的继承概念
  11. bugzilla dbd-mysql_Windows上配置bugzilla.doc
  12. 如何选择适合自己的相机?
  13. iconst、bipush、sipush、ldc指令的区别
  14. 数据库查询练习(一)
  15. 转载:刚入职美团两个月,就想离职了,每天加班到吐
  16. vim .bashrc编辑界面
  17. The Shawshank Redemption-6
  18. flask之flash
  19. 发送邮件报错:452 Too many recipients
  20. eNSP-配置路由器console接口密码与vty接口密码以及ftp服务

热门文章

  1. TIME_WAIT简介
  2. C++ STL 一般总结
  3. C++的精髓——虚函数
  4. 面试官:说说你对高性能秒杀系统的设计思考?
  5. 视频大时代下基础架构的演进
  6. 微软或在开发自己的 CPU、TikTok 发布电视版本、索尼撤下《赛博朋克2077》并为玩家退款|Decode the Week...
  7. 【大会】没有什么比把码率降低更爽的了
  8. 做音视频开发,你读对书了吗?(内有福利)
  9. 激进or务实?HEVC、AV1 和私有Codecs现状
  10. C/C++学习之路: 智能指针