阻塞队列实现原理

简介: 阻塞队列实现原理

阻塞队列实现原理

如果队列是空的,消费者会一直等待,当生产者添加元素时,消费者是如何知道当前队列有元素的呢?如果让你来设计阻塞队列你会如何设计,如何让生产者和消费者进行高效率的通信呢?让我们先来看看JDK是如何实现的。

使用通知模式实现。

所谓通知模式,就是当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用。通过查看JDK源码发现ArrayBlockingQueue使用了Condition来实现。

当往队列里插入一个元素时,如果队列不可用,那么阻塞生产者主要通过LockSupport.park(this)来实现。

public final void await() throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    Node node = addConditionWaiter();
    int savedState = fullyRelease(node);
    int interruptMode = 0;
    while (!isOnSyncQueue(node)) {
        LockSupport.park(this);
        if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
            break;
    }
    if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
        interruptMode = REINTERRUPT;
    if (node.nextWaiter != null) // clean up if cancelled
        unlinkCancelledWaiters();
    if (interruptMode != 0)
        reportInterruptAfterWait(interruptMode);
}
public static void park(Object blocker) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(false, 0L);
    setBlocker(t, null);
}

继续进入源码,发现调用setBlocker先保存一下将要阻塞的线程,然后调用unsafe.park阻塞当前线程。

private static void setBlocker(Thread t, Object arg) {
    // Even though volatile, hotspot doesn't need a write barrier here.
    UNSAFE.putObject(t, parkBlockerOffset, arg);
}

unsafe.park是个native方法

public native void putObject(Object var1, long var2, Object var4);

park这个方法会阻塞当前线程,只有以下4种情况中的一种发生时,该方法才会返回。

  • 与park对应的unpark执行或已经执行时。“已经执行”是指unpark先执行,然后再执行park的情况。
  • 线程被中断时。
  • 等待完time参数指定的毫秒数时。
  • 异常现象发生时,这个异常现象没有任何原因。

当线程被阻塞队列阻塞时,线程会进入WAITING(parking)状态。

总结

阻塞队列的实现原理是就是利用了通知模式,当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用

相关文章
|
设计模式 算法 程序员
程序员为何需要反复修改Bug?探寻代码编写中的挑战与现实
作为开发者,我们在日常开发过程中,往往会遇到反复修改bug的情况,而且不能一次性把代码写的完美无瑕,其实开发项目是一项复杂而富有挑战性的任务,即使经验丰富的程序员也难以在一次性编写完美无瑕地完成代码,我个人觉得一次性写好代码是不可能完成的事情。虽然在设计之初已经尽力思考全面,并在实际操作中力求精确,但程序员仍然需要花费大量时间和精力来调试和修复Bug。那么本文就来分享程序员需要反复修改Bug的原因,以及在开发中所面临的复杂性与挑战。
369 1
程序员为何需要反复修改Bug?探寻代码编写中的挑战与现实
|
资源调度
There appears to be trouble with your network connection.Retrying
There appears to be trouble with your network connection.Retrying
2196 0
There appears to be trouble with your network connection.Retrying
|
11月前
|
监控 数据可视化 搜索推荐
【Python篇】matplotlib超详细教程-由入门到精通(下篇)2
【Python篇】matplotlib超详细教程-由入门到精通(下篇)
133 9
|
11月前
|
JavaScript 前端开发
使用通义灵码的@workspace和@terminal功能,快速熟悉并开发一个在线商城项目
使用通义灵码的@workspace和@terminal功能,快速熟悉并开发一个在线商城项目
|
Ubuntu 开发工具 git
在Ubuntu 18.04上安装Git【快速入门】
在Ubuntu 18.04上安装Git【快速入门】
206 0
|
SQL 存储 安全
【SQL刷题】Day3----SQL必会的常用函数专项练习
【SQL刷题】Day3----SQL必会的常用函数专项练习
299 0
【SQL刷题】Day3----SQL必会的常用函数专项练习
|
存储 机器学习/深度学习 人工智能
摆脱 OpenAI 依赖,8 分钟教你用开源生态构建全栈 AI 应用
大模型时代的到来使得 AI 应用开发变得更加轻松、省时,尤其是在 CVP Stack 的范式下,开发者甚至可以用一个周末的时间做出一个完整的应用程序。
706 1
|
搜索推荐 算法 数据处理
OpenSearch上线实时热搜、个性化底纹功能
热搜和底纹处于搜索整个流程的最上游,通过推荐热门、优质、多样化的查询词,对用户搜索意图起到重要的引导作用。OpenSearch上线实时热搜和个性化底纹功能,满足企业多样化搜索引导需求。
1219 1
OpenSearch上线实时热搜、个性化底纹功能
|
Java API Android开发
|
Java
java 一对多、多对多关系示例
java 一对多、多对多关系示例
422 0

热门文章

最新文章