什么是阻塞队列?有那7种阻塞队列?为什么需要阻塞队列?通过剖析JDK 1.8 源码了解源码设计的精髓和巧妙的地方,并运用在我们实际的项目中,他山之石,可以攻玉。
感觉并发编程上面的解释不是很容易理解,我们看下源码Doug Lea大佬的注释,意思是阻塞队列支持检索的时候可以等待队列变成非空(也就是阻塞等待), 存储元素的时候,等待空间可用。
BlockingQueue方法有四种形式,具有不同的处理操作的方法,这些操作不能立即得到满足,但可能在将来的某个时候得到满足:
JDK 7提供了7个阻塞队列,如下。
ArrayBlockingQueue是一个用数组实现的有界阻塞队列。此队列按照先进先出(FIFO)的原 则对元素进行排序。
看下ArrayBlockingQueue 依赖继承关系,底层是以数组
Object[] items;保存元素的。
LinkedBlockingQueue是一个用链表实现的有界阻塞队列。此队列的默认和最大长度为 Integer.MAX_VALUE。此队列按照先进先出的原则对元素进行排序。
PriorityBlockingQueue是一个支持优先级的无界阻塞队列。默认情况下元素采取自然顺序 升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数Comparator来对元素进行排序。需要注意的是不能保证同优先级元素的顺序。
DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队 列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。 只有在延迟期满时才能从队列中提取元素。
使用场景:
SynchronousQueue是一个不存储元素的阻塞队列。每一个put操作必须等待一个take操作,否则不能继续添加元素。
它支持公平访问队列。默认情况下线程采用非公平性策略访问队列。使用以下构造方法可以创建公平性访问的SynchronousQueue,如果设置为true,则等待的线程会采用先进先出的顺序访问队列。
LinkedTransferQueue是一个由链表结构组成的无界阻塞TransferQueue队列。相对于其他阻 塞队列,LinkedTransferQueue多了tryTransfer和transfer方法。
2.6.1 transfer方法
2.6.2 tryTransfer方法
LinkedBlockingDeque是一个由链表结构组成的双向阻塞队列。
我们初学线程池可能会有一个疑问,如果队列是空的,消费者会一直等待,当生产者添加元素时,消费者是如何知道当前队列有元素的呢? 如果是你你会怎么去设计?
使用通知模式实现。所谓通知模式,就是当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用。
以JDK ArrayBlockingQueue 源码分析
我们看下put操作,源码不复杂,我简单解释一下while条件,判断如果队列满了, notFull.await() 等待,当队列不满了,继续执行入队操作。
take方法
对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
不用多说,相信大家都有一个共识:无论什么行业,最牛逼的人肯定是站在金字塔端的人。所以,想做一个牛逼的程序员,那么就要让自己站的更高,成为技术大牛并不是一朝一夕的事情,需要时间的沉淀和技术的积累。
现在竞争这么激烈,只有通过不断学习,提高自己,才能保持竞争力。
对于一些不知道学习什么,没有一个系统路线的程序员,这里给大家提供一些学习资料
需要的小伙伴,可以一键三连, 点击这里获取免费领取方式!
内容涵盖:Java基础、JVM、高并发、多线程、分布式、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、数据库、云计算等
需要的小伙伴,可以一键三连, 点击这里获取免费领取方式!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70000430/viewspace-2787397/ ,如需转载,请注明出处,否则将追究法律责任。