IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JAVA容器系列一:ArrayBlockingQueue源码解读 -> 正文阅读

[Java知识库]JAVA容器系列一:ArrayBlockingQueue源码解读

作者:recommend-item-box type_blog clearfix

阻塞队列(BlockingQueue)被广泛使用在“生产者-消费者”问题中,其原因是BlockingQueue提供了可阻塞的插入和可阻塞的移除方法。当队列容器满了,插入线程会被阻塞,直到队列容器空出位置。当队列容器空了,移除线程会被阻塞,直到队列容器不为空.
BlockingQueue 方法以四种形式出现:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:
在这里插入图片描述

成员变量

	 //用来存放数据的数组
    final Object[] items;

    //如果下次要获取数据,获取数据的位置
    int takeIndex;

    //如果下次要插入数据,插入数据的位置
    int putIndex;

    //数据的总数
    int count;

    //保证线程安全的锁
    final ReentrantLock lock;

    //Condition等待队列,主要用于获取数据的线程
    private final Condition notEmpty;

    //Condition等待队列,主要用于插入数据的线程
    private final Condition notFull;

Put方法:

public void put(E e) throws InterruptedException {
		//判断数组是否为null
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        //尝试获取锁(可响应中断)
        lock.lockInterruptibly();
        try {
        	//判断总数count是否等于数组的长度,如果等于,表示数组满了
            while (count == items.length)
            	//当前线程进入到notFull等待队列中
                notFull.await();
            //当阻塞队列不满的时候,进行入队操作
            enqueue(e);
        } finally {
        	//释放锁
            lock.unlock();
        }
    }

put()方法调用了enqueue()方法进行入队操作:

private void enqueue(E x) {
        //获得数组
        final Object[] items = this.items;
        //将元素x存放在数组的putIndex位置上
        items[putIndex] = x;
        //如果插入的位置已经是数组中的最后一个位置了,那么就将putIndex置为0
        //因为已经到达最后一个了,那就只能从第一个位置插入元素
        if (++putIndex == items.length)
            putIndex = 0;
       //总数+1
        count++;
        //唤醒notEmpty队列中等待获取数据的线程
        notEmpty.signal();
    }

Take方法:

 public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        //尝试获得锁(可响应中断)
        lock.lockInterruptibly();
        try {
        	//如果队列为空
            while (count == 0)
            	//进入到notEmpty队列进行等待
                notEmpty.await();
            //返回获取的元素
            return dequeue();
        } finally {
        	//释放锁
            lock.unlock();
        }
    }

take()方法调用dequeue()方法来从队列获取元素:

private E dequeue() {
        //获取数组
        final Object[] items = this.items;
        @SuppressWarnings("unchecked")
        //获得takeIndex位置上的数据
        E x = (E) items[takeIndex];
        //将takeIndex位置置为null
        items[takeIndex] = null;
        //判断是否是获取最后一个位置的数据,如果是,下一次就需要从0开始获取
        if (++takeIndex == items.length)
            takeIndex = 0;
        //总数减一
        count--;
        //这个是itrs类实现的迭代器,是ArrayBlcokingQueue的一个内部类
        if (itrs != null)
            itrs.elementDequeued();
        //因为取出了一个元素,所以队列中肯定要空位置,于是唤醒需要插入数据的线程。
        notFull.signal();
        return x;
    }

Offer方法:

  public boolean offer(E e) {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (count == items.length)
                return false;
            else {
                enqueue(e);
                return true;
            }
        } finally {
            lock.unlock();
        }
    }

Poll()方法:

 public E poll() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return (count == 0) ? null : dequeue();
        } finally {
            lock.unlock();
        }
    }
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:36:26  更:2022-03-13 21:38:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:51:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码