Java并发--阻塞队列的实现原理

阻塞队列的实现原理

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

在这里插入图片描述
当往队列里插入一个元素时,如果队列不可用,那么阻塞生产者主要通过LockSupport.park(this)来实现。
在这里插入图片描述
继续进入源码,发现调用setBlocker先保存一下将要阻塞的线程,然后调用unsafe.park阻塞当前线程。

在这里插入图片描述
unsafe.park是个native方法,代码如下。
在这里插入图片描述

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

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

继续看一下JVM是如何实现park方法:park在不同的操作系统中使用不同的方式实现,在Linux下使用的是系统方法pthread_cond_wait实现。实现代码在JVM源码路径src/os/linux/vm/os_linux.cpp里的os::PlatformEvent::park方法,代码如下。
在这里插入图片描述
pthread_cond_wait是一个多线程的条件变量函数,cond是condition的缩写,字面意思可以理解为线程在等待一个条件发生,这个条件是一个全局变量。这个方法接收两个参数:

一个共享变量_cond,一个互斥量_mutex。

而unpark方法在Linux下是使用pthread_cond_signal实现的。

park方法在Windows下则是使用WaitForSingleObject实现的。想知道pthread_cond_wait是如何实现的,可以参考glibc-2.5的nptl/sysdeps/pthread/pthread_cond_wait.c。

当线程被阻塞队列阻塞时,线程会进入WAITING(parking)状态。我们可以使用jstack dump阻塞的生产者线程看到这点,如下。

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值