精华内容
下载资源
问答
  • Java中的阻塞队列接口BlockingQueue继承自Queue接口。BlockingQueue接口提供了3个添加元素方法:add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出IllegalStateException异常;offer:添加元素到...

    Java中的阻塞队列接口BlockingQueue继承自Queue接口。

    BlockingQueue接口提供了3个添加元素方法:

    add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出IllegalStateException异常;

    offer:添加元素到队列里,添加成功返回true,添加失败返回false;

    put:添加元素到队列里,如果容量满了会阻塞直到容量不满。

    3个删除方法:

    poll:删除队列头部元素,如果队列为空,返回null。否则返回元素;

    remove:基于对象找到对应的元素,并删除。删除成功返回true,否则返回false;

    take:删除队列头部元素,如果队列为空,一直阻塞到队列有元素并删除。

    常用的阻塞队列具体类有ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、LinkedBlockingDeque等。

    本文以ArrayBlockingQueue和LinkedBlockingQueue为例,分析它们的实现原理。

    ArrayBlockingQueue

    ArrayBlockingQueue的原理就是使用一个可重入锁和这个锁生成的两个条件对象进行并发控制(classic two-condition algorithm)。

    ArrayBlockingQueue是一个带有长度的阻塞队列,初始化的时候必须要指定队列长度,且指定长度之后不允许进行修改。

    它带有的属性如下:

    // 存储队列元素的数组,是个循环数组

    final Object[] items;

    // **的索引,用于take,poll,peek,remove方法

    int takeIndex;

    // 放数据的索引,用于put,offer,add方法

    int putIndex;

    // 元素个数

    int count;

    // 可重入锁

    final ReentrantLock lock;

    // notEmpty条件对象,由lock创建

    private final Condition notEmpty;

    // notFull条件对象,由lock创建

    private final Condition notFull;

    数据的添加

    ArrayBlockingQueue有不同的几个数据添加方法,add、offer、put方法。

    add方法:

    public boolean add(E e) {

    if (offer(e))

    return true;

    else

    throw new IllegalStateException("Queue full");

    }

    add方法内部调用offer方法如下:

    public boolean offer(E e) {

    checkNotNull(e); // 不允许元素为空

    final ReentrantLock lock = this.lock;

    lock.lock(); // 加锁,保证调用offer方法的时候只有1个线程

    try {

    if (count == items.length) // 如果队列已满

    return false; // 直接返回false,添加失败

    else {

    insert(e); // 数组没满的话调用insert方法

    return true; // 返回true,添加成功

    }

    } finally {

    lock.unlock(); // 释放锁,让其他线程可以调用offer方法

    }

    }

    insert方法如下:

    private void insert(E x) {

    items[putIndex] = x; // 元素添加到数组里

    putIndex = inc(putIndex); // 放数据索引 1,当索引满了变成0

    count; // 元素个数 1

    notEmpty.signal(); // 使用条件对象notEmpty通知,比如使用take方法的时候队列里没有数据,被阻塞。这个时候队列insert了一条数据,需要调用signal进行通知

    }

    put方法:

    public void put(E e) throws InterruptedException {

    checkNotNull(e); // 不允许元素为空

    final ReentrantLock lock = this.lock;

    lock.lockInterruptibly(); // 加锁,保证调用put方法的时候只有1个线程

    try {

    while (count == items.length) // 如果队列满了,阻塞当前线程,并加入到条件对象notFull的等待队列里

    notFull.await(); // 线程阻塞并被挂起,同时释放锁

    insert(e); // 调用insert方法

    } finally {

    lock.unlock(); // 释放锁,让其他线程可以调用put方法

    }

    }

    ArrayBlockingQueue的添加数据方法有add,put,offer这3个方法,总结如下:

    add方法内部调用offer方法,如果队列满了,抛出IllegalStateException异常,否则返回true

    offer方法如果队列满了,返回false,否则返回true

    add方法和offer方法不会阻塞线程,put方法如果队列满了会阻塞线程,直到有线程消费了队列里的数据才有可能被唤醒。

    这3个方法内部都会使用可重入锁保证原子性。

    数据的删除

    ArrayBlockingQueue有不同的几个数据删除方法,poll、take、remove方法。

    poll方法:

    public E poll() {

    final ReentrantLock lock = this.lock;

    lock.lock(); // 加锁,保证调用poll方法的时候只有1个线程

    try {

    return (count == 0) ? null : extract(); // 如果队列里没元素了,返回null,否则调用extract方法

    } finally {

    lock.unlock(); // 释放锁,让其他线程可以调用poll方法

    }

    }

    poll方法内部调用extract方法:

    private E extract() {

    final Object[] items = this.items;

    E x = this.

    Tag标签:

    展开全文
  • if(nexti!=putIndex){items[i]=items[nexti];i=nexti;}else{items[i]=null;putIndex=i;break;}}}--count;//元素个数-1notFull.signal();//应用前提对象notFull通知,比如...这个时刻花费了一条数据,队列没满了,...

    if (nexti != putIndex) {

    items[i] = items[nexti];

    i = nexti;

    } else{

    items[i] = null;

    putIndex = i;

    break;

    }

    }

    }

    --count; // 元素个数-1

    notFull.signal(); // 应用前提对象notFull通知,比如应用put办法放数据的时刻队列已满,被壅塞。这个时刻花费了一条数据,队列没满了,就须要调用signal进行通知

    }

    ArrayBlockingQueue的删除数据办法有poll,take,remove这3个办法,总结如下:

    poll办法对于队列为空的情况,返回null,不然返回队列头部元素。

    remove办法取的元素是基于对象的下标值,删除成功返回true,不然返回false。

    poll办法和remove办法不会壅塞线程。

    take办法对于队列为空的情况,会壅塞并挂起当前哨程,直到稀有据参加到队列中。

    这3个办法内部都邑调用notFull.signal办法通知正在等待队列满情况下的壅塞线程。

    LinkedBlockingQueue

    LinkedBlockingQueue是一个应用链表完成队列操作的壅塞队列。链表是单向链表,而不是双向链表。

    内部应用放锁和拿锁,这两个锁实现壅塞(“two lock queue” algorithm)。

    它带有的属性如下:// 容量大年夜小

    private final intcapacity;

    // 元素个数,因为有2个锁,存在竞态前提,应用AtomicInteger

    private final AtomicInteger count= new AtomicInteger(0);

    // 头结点

    private transient Node head;

    // 尾节点

    private transient Node last;

    // 拿锁

    private final ReentrantLock takeLock = new ReentrantLock();

    // 拿锁的前提对象

    private final Condition notEmpty = takeLock.newCondition();

    // 放锁

    推荐阅读

    核心提示: 大年夜量来自于发念头和其他一些关键部件的监控数据,使得猜测性维修具备了可行性。越来越多的数据的收集和分析对象正在被开辟或者投入应用。大年夜量来自于发念头和其他一些关>>>详细阅读

    地址:http://www.17bianji.com/lsqh/34749.html

    展开全文
  • 这篇文章主要介绍了java阻塞队列实现原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下阻塞队列与普通队列的不同在于。当队列是空的时候,从队列中...

    这篇文章主要介绍了java阻塞队列实现原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

    dd4eac39e5ae29d2a0bdc706b2531bfe.png

    线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素

    从5.0开始,JDK在Java.util.concurrent包里提供了阻塞队列的官方实现。尽管JDK中已经包含了阻塞队列的官方实现。

    阻塞队列的实现

    阻塞队列的实现类似于带上限的Semaphore的实现。

    废话不多说:

    package com.huojg.test;

    import java.util.LinkedList;

    import java.util.List;

    public class BlockingQueue {

    private List queue = new LinkedList();

    private int limit = 10;

    public BlockingQueue(int limit){

    this.limit = limit;

    }

    public synchronized void enqueue(Object item)

    throws InterruptedException {

    while(this.queue.size() == this.limit) {

    wait();

    }

    if(this.queue.size() == 0) {

    notifyAll();

    }

    this.queue.add(item);

    }

    public synchronized Object dequeue()

    throws InterruptedException{

    while(this.queue.size() == 0){

    wait();

    }

    if(this.queue.size() == this.limit){

    notifyAll();

    }

    return this.queue.remove(0);

    }

    }

    必须注意到,在enqueue和dequeue方法内部,只有队列的大小等于上限(limit)或者下限(0)时,才调用notifyAll方法。如果队列的大小既不等于上限,也不等于下限,任何线程调用enqueue或者dequeue方法时,都不会阻塞,都能够正常的往队列中添加或者移除元素。

    在Java中,对于Lock和Condition可以理解为对传统的synchronized和wait/notify机制的替代。

    wait/notify有个限制,调用wait/notify的线程必须持有对象的锁。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • 阻塞队列实现原理 核心: lock锁+多条件(condition)的阻塞控制 Java中的阻塞队列使用BlockingQueue封装了根据condition条件阻塞线程的过程,使得我们不需要求关系繁琐的await和signal操作。 以生产消费者模式举例...

    阻塞队列的实现原理

    核心: lock锁+多条件(condition)的阻塞控制
    Java中的阻塞队列使用BlockingQueue封装了根据condition条件阻塞线程的过程,使得我们不需要求关系繁琐的await和signal操作。
    以生产消费者模式举例,使用阻塞队列可以不关系什么时候阻塞生产,什么时候阻塞消费。
    实现: 各个阻塞队列都实现了BlockingQueue接口


    常用阻塞队列:
    ArrayBlockingQueue:
    是一个用数组实现的、有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,它不能够存储无限多数量的元素。
    LinkedBlockingQueue:
    这是一种基于链表的阻塞队列;即,内部是以链表结构对其元素进行存储。
    SynchronousQueue:
    ​ SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素

    展开全文
  • Java 阻塞队列原理

    2021-02-15 19:28:02
    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景...
  • 文章目录一、阻塞队列介绍1.1 Queue接口1.2 BlockingQueue接口1.3 BlockingQueue常用方法示例二、阻塞队列特性2.1 阻塞2.2 是否有界三、应用场景四、常用阻塞队列精讲 一、阻塞队列介绍 1.1 Queue接口 public ...
  • 用在生产者消费者模式中, 平衡两者性能差异 解耦 有界 无界 Android中的handler部分的MessageQueue 就是一个优先级队列
  • 接下来分别从服务端和客户端来阐述这一逻辑的实现原理。Redis Server:redis实现了一套事件触发模型,主要处理两种事件:I/O事件(文件事件)和定时事件。而处理它们的就靠一个EventLoop线程。同时redis还提供了丰富的...
  • 什么是阻塞队列阻塞队列提供了两个阻塞行为的操作,当队列为空时,获取元素的线程会一直等待队列非空才会返回值,当队列满时,添加元素线程同理也会等待队列可用才执行添加。阻塞队列常用于生产者和消费者场景,生产...
  • 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时, 获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于 生产者和消费者的...
  • Java阻塞队列实现

    2020-12-21 12:01:10
    阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列...
  • 展开全部阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作62616964757a686964616fe59b9ee7ad9431333337393566将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞...
  • Java实现一个阻塞队列

    2020-12-21 12:01:11
    循环队列是如何实现的,以及实现原理,判断栈满栈空的条件为何这样写,参考Java语言实现一个循环队列阻塞队列内部构造及初始化使用ReetrantLock,进行多线程的锁的控制,以及使用Condition进行实现队列中操作等待...
  • 1. 什么是阻塞队列阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产...
  • 在之前的线程池的介绍中我们看到了很多阻塞队列,这篇文章我们主要来说说阻塞队列的事。阻塞队列也就是BlockingQueue,这个类是一个接口,同时继承了Queue接口,这两个接口都是在JDK5中加入的 。BlockingQueue阻塞...
  • 前言本文通过一个简单的例子,来展现如何使用阻塞队列(BlockingQueue)来实现异步通信功能。(这是笔者在做日志记录时,用来做异步操作的)BlockingQueue的核心方法放入数据:offer(anObject):表示如果可能的话,将an...
  • Redis阻塞/非阻塞队列

    2021-04-28 00:42:38
    阻塞队列RPUSH key value [value ...]RPOP keyLPUSH key value [value ...]LPOP keyR/LPUSH都是后进先出操作,组合起来则是先进先出,属于非阻塞操作,即:不管有无找到指定键值都立即返回。阻塞队列RPUSH key ...
  • 阻塞队列原理解析

    2021-02-03 13:31:15
    2、阻塞队列的使用案例 2.1 案例 注册成功后增加积分 假如我们模拟一个场景,就是用户注册的时候,在注册成功以后发放积分。这个场景在一般来说,我们会这么去实现: 但是实际上,我们需要考虑两个问题: 性能,在...
  • 1. 悲观锁和乐观锁 1.1. 乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会...在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。java.util.conc
  • 什么是阻塞队列 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。 支持阻塞的插入方法:当队列满时,队列会阻塞插入元素的线程,直到队列不满。 支持阻塞的...
  • java原理篇之阻塞队列

    2021-07-12 14:39:57
    阻塞队列接口结构和实现类2.阻塞队列api之抛出异常组3.阻塞队列api之返回布尔值组4.阻塞队列api之阻塞和超时控制5.阻塞队列之同步SynchronousQueue队列 1.阻塞队列接口结构和实现类 概念 队列:队列就可以想成是一个...
  • Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。...
  • Java面试之阻塞队列

    2021-03-24 20:22:09
    阻塞队列 概念 队列 队列就可以想成是一个数组,从一头进入,一头出去,排队买饭(FIFO),和栈是一样的FIFO 阻塞队列 BlockingQueue 阻塞队列,排队拥堵,首先它是一个队列,而一个阻塞队列在数据结构中所起的作用...
  • java-阻塞队列

    2021-09-22 20:20:15
    阻塞队列 基本概念 什么是队列? 看下面的图理解理解: 当然,我作为专业的程序员,在我眼里,上面的图就是这样的: 什么是阻塞队列呢? 大概是这样的: 你坐过公交车吗? 不对应该是挤过公交吗?就是那种只有后面...
  • 怎么确保线程池最大线程数达到后,提交的任务不丢失new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler); 参数: corePoolSize(线程池...java阻塞...
  • 本文转载自互联网,侵删本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看喜欢的话麻烦点下Star哈文章同步发于我的个人博客:www.how2playlife.com本×××术江湖】的《Java...
  • 1. Redis分布式锁实现原理分布式锁本质上要实现的目标就是在Redis里面占一个“茅坑”,当别的进程也要来占时,发现已经有人蹲在那里了,就只好放弃或者稍后再试。占坑一般是使用setnx(set if not exists)指令,只...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 82,757
精华内容 33,102
关键字:

java阻塞队列实现原理

java 订阅