前言

从之前的阻塞队列的源码分析中,我们知道,JDK 中的阻塞队列是使用 ReentrantLock 和 Condition 实现了,我们今天来个简易版的。代码如下:

代码

  1. public class BoundedBuffer {
  2. final ReentrantLock lock = new ReentrantLock();
  3. final ConditionObject notFull = (ConditionObject) lock.newCondition();
  4. final ConditionObject notEmpty = (ConditionObject) lock.newCondition();
  5. final Object[] items = new Object[100];
  6. int putptr, takeptr, count;
  7. public void put(Object x) throws InterruptedException {
  8. lock.lock();
  9. try {
  10. // 当数组满了
  11. while (count == items.length) {
  12. // 释放锁,等待
  13. notFull.await();
  14. }
  15. // 放入数据
  16. items[putptr] = x;
  17. // 如果到最后一个位置了,下标从头开始,防止下标越界
  18. if (++putptr == items.length) {
  19. // 从头开始
  20. putptr = 0;
  21. }
  22. // 对 count ++ 加加
  23. ++count;
  24. // 通知 take 线程,可以取数据了,不必继续阻塞
  25. notEmpty.signal();
  26. } finally {
  27. lock.unlock();
  28. }
  29. }
  30. public Object take() throws InterruptedException {
  31. lock.lock();
  32. try {
  33. // 如果数组没有数据,则等待
  34. while (count == 0) {
  35. notEmpty.await();
  36. }
  37. // 取数据
  38. Object x = items[takeptr];
  39. // 如果到数组尽头了,就从头开始
  40. if (++takeptr == items.length) {
  41. // 从头开始
  42. takeptr = 0;
  43. }
  44. // 将数量减1
  45. --count;
  46. // 通知阻塞的 put 线程可以装填数据了
  47. notFull.signal();
  48. return x;
  49. } finally {
  50. lock.unlock();
  51. }
  52. }

其实,这并不是我写的,而是 Condition 接口的 JavaDoc 文档中写的。并且文档中说,请不要再次实现这个队列,因为 JDK 内部已经是实现了。原话如下:

(The {@link java.util.concurrent.ArrayBlockingQueue} class provides this functionality, so there is no reason to implement this sample usage class.)

楼主只是觉得这个代码写的挺好的,所以分享一下,其中关键的还是 Condition 和重入锁,重入锁的核心源码我们已经看过了,今天来看看 Condition 的源码。所以我们今天使用了这个代码作为一个入口。

可以看到,Condition 的重要方法就是 await 和 signal,类似 Object 类的 wait 和 notify 方法。

我们后面会详细讲讲这两个方法的实现。

使用 ReentrantLock 和 Condition 实现一个阻塞队列的更多相关文章

  1. 利用ReentrantLock简单实现一个阻塞队列

    借助juc里的ReentrantLock实现一个阻塞队列结构: package demo.concurrent.lock.queue; import java.util.concurrent.lock ...

  2. 用Java如何设计一个阻塞队列,然后说说ArrayBlockingQueue和LinkedBlockingQueue

    前言 用Java如何设计一个阻塞队列,这个问题是在面滴滴的时候被问到的.当时确实没回答好,只是说了用个List,然后消费者再用个死循环一直去监控list的是否有值,有值的话就处理List里面的内容.回 ...

  3. 浅谈Java中的Condition条件队列,手摸手带你实现一个阻塞队列!

    条件队列是什么?可能很多人和我一样答不出来,不过今天终于搞清楚了! 什么是条件队列 条件队列:当某个线程调用了wait方法,或者通过Condition对象调用了await相关方法,线程就会进入阻塞状态 ...

  4. 使用lock和condition实现的阻塞队列-字符串

    在jdk 的API中提供了一个字符串的阻塞队列 : class BoundedBuffer { final Lock lock = new ReentrantLock(); final Conditi ...

  5. ReentrantLock与Condition构造有界缓存队列与数据栈

    通过ReentrantLock与Condition的设计,以数组为基础,可以实现简单的队列和栈的数据结构,临界阻塞的效果. ReentrantLock相对于synchronized比较大的一个区别是有 ...

  6. 16_Queue_利用wait()和notify()编写一个阻塞队列

    [线程间通信概念] 线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体必用方式之一.当线程存在通信指挥,线程间的交互性会更强大,在提高CPU利用率的同 ...

  7. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  8. 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?

    多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...

  9. 聊聊高并发(十四)理解Java中的管程,条件队列,Condition以及实现一个堵塞队列

    这篇里面有一些主要的概念,理解概念是件有意义的事情,仅仅有理解概念才干在面对详细问题的时候找到正确的解决思路.先看一下管程的概念 第一次在书上看到管程这个中文名称认为非常迷糊,管程究竟是个什么东东,于 ...

随机推荐

  1. 6.python3爬虫之urllib库

    # 导入urllib.request import urllib.request # 向指定的url发送请求,并返回服务器响应的类文件对象 response = urllib.request.urlo ...

  2. MAC系统下用Idea创建spring boot工程 基于maven

    1.创建项目 打开idea编辑器,选择file  -> new -> project 点击next 依次填入group,artifact 填写完成之后再点击“next” 根据自己的需求在最 ...

  3. ctags的如何生成tags文件

    tags 在使用vim编程和浏览代码是非常有用.可以用CTRL+]和CTRL+t 来回跳转关键字.先生成自己工作目录的tags.最简单粗暴用法: $cd yourwork $ctags -R * 这样 ...

  4. c#中快速排序的学习

    最近看了一句话,说的是在现实生活中,会写字的人不见得会写出好文章,学习编程语言就像是学会了写字,学会了编程语言并不一定能写出好程序. 我觉得就是很有道理,以前读书的时候,基本学完了C#中的语法知识,算 ...

  5. 不一样的网络流系列——Dinic跑得快

    前言 摆王兴致冲冲地跑到我们机房来对我说跟你讲一个黑科技... Dinic的神奇优化 Dinic优化 我们发现如果Dinic不建反向边会跑的飞起(当然Wa是必然的) 所以考虑在加反向边的基础上优化. ...

  6. PS插件CameraRaw-HSL色彩模式

    一.HSL百度百科 HSL色彩模式是工业界的一种颜色标准,是通过对色相(H).饱和度(S).明度(L)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,HSL即是代表色相,饱和度,明度三 ...

  7. 深度学习:浅谈RNN、LSTM+Kreas实现与应用

    主要针对RNN与LSTM的结构及其原理进行详细的介绍,了解什么是RNN,RNN的1对N.N对1的结构,什么是LSTM,以及LSTM中的三门(input.ouput.forget),后续将利用深度学习框 ...

  8. 杀掉所有 skynet 进程

    ps aux | grep skynet | awk '/config/{print $2}' | xargs kill

  9. CodeForces - 940C + CodeForces - 932B (两道比较好的模拟题)

    940C链接:http://codeforces.com/problemset/problem/940/C C. Phone Numbers time limit per test 2 seconds ...

  10. Vue 项目配置

    配置Vue的app项目首先需要配置本地环境. 1.下载node.js并且安装.(根据自己电脑参数进行选择) 打开cmd,检查是否安装成功. 分别输入: node -v npm -v 结果如图正确显示出 ...