一、基本思想
基于数组的阻塞队列,它既有队列的特性--先进先出(first-in-first-out),又有数组的特性--有限大小(bounded-buffer),一旦被创建,就不会增加容量。
二、源码解析
2.1基本数据
/** The queued items */ private final E[] items; //数组 /** 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; //元素个数,不是容量 /* * Concurrency control uses the classic two-condition algorithm * found in any textbook. */ /** Main lock guarding all access */ private final ReentrantLock lock; //可重入锁,保证线程并发访问 /** Condition for waiting takes */ private final Condition notEmpty; //消费者线程可以获得资源的条件 /** Condition for waiting puts */ private final Condition notFull;//生产者线程可以继续生产的条件
2.2 get
public E poll() {//获取并删除队列的头元素,如果没有就返回空 final ReentrantLock lock = this.lock; lock.lock(); //锁住 try { if (count == 0) return null; E x = extract(); return x; } finally { lock.unlock(); } } public E take() throws InterruptedException { //获取并删除队列的头元素, //如果没有就阻塞一直到有,或者线程被打断 final ReentrantLock lock = this.lock; lock.lockInterruptibly();//获得锁,除非线程被打断 try { try { while (count == 0) notEmpty.await();//循环等待,一直到有为止,为什么要循环等待呢, //因为在多个线程等待的情况下,虽然会唤醒,当还是存在资源被其它等待的线程占用的情况 } catch (InterruptedException ie) { notEmpty.signal(); // propagate to non-interrupted thread throw ie; } E x = extract(); return x; } finally { lock.unlock(); } } private E extract() { final E[] items = this.items; E x = items[takeIndex]; items[takeIndex] = null; //获取最后一个之后,数组的这个坐标引用指向空 takeIndex = inc(takeIndex);//头部坐标到下一个 --count;//数据个数减少一个 notFull.signal();//唤醒一个因容量满而停止生产的线程 return x; } final int inc(int i) { return (++i == items.length)? 0 : i;//利用头尾相接来模拟一个循环的队列 }
2.3 put
三、适用范围
来自源码注释的解释:
这个类有可选的公平策略对于等待的生产者或者消费者线程来说,默认情况下不启动公平策略。因为公平策略虽然减少可变性和可以避免线程饥饿的情况发生,但是通常会减少吞吐量(throughput)
个人理解:
对消费者来说,如果有很多消费者都在等待生产者生产产品,但是因为大家都没有顺序,特别是在资源比较紧张的情况,很有可能有的线程一直处于饥饿状态(即一直没有抢到产品),悲剧!
对生产者来说,可能有的线程忙的不可开交,另外一些线程闲的蛋疼。
(某些国有企业的人,应该深有感触)
四、测试
相关推荐
Java并发编程是Java开发中的重要领域,而Java并发工具包(Java Concurrency Utility,简称JUC)则是Java标准库提供的一套强大而丰富的工具,它极大地简化了多线程环境下的编程工作。JUC主要包含在`java.util....
这个集合提供了一系列高效、线程安全的类和接口,用于简化多线程环境下的编程任务。本资源"JUC代码收集,java高并发多线程学习"显然是一个专注于探讨和学习JUC库的资料包。 JUC库包含多个子包,如`concurrent`, `...
Java中的`BlockingQueue`接口是Java并发编程的重要组件,它位于`...在使用时,选择合适的实现类,如`ArrayBlockingQueue`, `LinkedBlockingQueue`, `LinkedBlockingDeque`等,可以根据具体需求来优化性能和内存使用。
Java并发编程领域的JUC(Java Util Concurrency)是Java平台中的一个重要组成部分,它为多线程编程提供了丰富的工具和框架。"哔哩哔哩JUC狂老师笔记.zip"中的笔记内容,显然聚焦于讲解如何有效地利用JUC库来提升并发...
本资源"juc从入门到精通实例代码.rar"是一份深入学习JUC的实践教程,旨在帮助开发者掌握JUC的核心概念和实用技巧。 1. **并发基础** - **线程与进程**:首先,我们需要了解线程和进程的基本概念,以及它们在操作...
Java并发编程库(Java Concurrency Utility,简称JUC)是Java平台中用于高效并发处理的重要组件,主要包含在`java.util.concurrent`包及其子包下。JUC为开发者提供了丰富的并发工具类,使得多线程编程更加安全、高效...
CountDownLatch 是 Juc 架包下的一种同步工具,用于等待一组线程的完成。只有在给定的数字变为 0 之后,await 才会执行下一步。 8. CyclicBarrier CyclicBarrier 是 Juc 架包下的一种同步工具,用于等待一组线程的...
这些集合在多线程环境下能保证数据的一致性和线程安全性。 6. **原子类**: `java.util.concurrent.atomic` 包含一系列原子变量类,如`AtomicInteger`、`AtomicLong`、`AtomicReference`等,它们提供了一种无锁编程...
- **Java集合框架**:这是Java编程中非常重要的一个部分,主要用于处理数据集合。 - **ArrayList**:一种动态数组实现的数据结构,适用于频繁查询场景。 - **LinkedList**:双链表实现的数据结构,适合频繁插入...
在IT行业中,尤其是在Java开发领域,`java.util.concurrent`(JUC)包是并发编程的核心工具包,它提供了丰富的类和接口,使得开发者能够高效、安全地处理多线程环境中的任务。`Concurrent.zip`文件很可能是包含了...
- 面向对象编程(OOP)是Java的核心概念之一,它主要包括四个特性:封装、继承、多态和抽象。 - **封装**:将数据和操作数据的方法封装在一个对象中,隐藏对象的实现细节,只暴露必要的接口。 - **继承**:允许一个...