借助juc里的ReentrantLock实现一个阻塞队列结构:


package demo.concurrent.lock.queue; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; /**
* @author sunqinwen
* @version \: SimpleQueue.java,v 0.1 2019-01-16 14:47
* 利用重入锁和重入锁的线程调度实现的简单阻塞队列
*/
public class SimpleQueue { private static ReentrantLock lock = new ReentrantLock(); private T[] nodes; private int tail = 0; // 入元素下标 private int count = 0; // 元素个数 private int head = 0; // 出元素下标 public SimpleQueue(int size) {
nodes = (T[]) new Object[size];
} private static Condition notFull = lock.newCondition(); private static Condition notEmpty = lock.newCondition(); public void put(T t) {
try {
lock.lock();
if (count == nodes.length) { // 队列已满,阻塞
System.out.println("目前队列已满,等待取值中");
notFull.await();
}
if (tail > (nodes.length - 1)) { // 当前游标值已经大于数组游标最大值了,则从0开始计算
tail = 0;
}
nodes[tail] = t; // 给当前游标位赋值
count++; // 入元素元素个数+1
tail++; // 游标值+1
notEmpty.signalAll(); // 走到这里说明队列内至少有一个元素,则唤醒取值
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public T take() {
T t = null;
try {
lock.lock();
if (count == 0) { // 队列已空,等待加值
System.out.println("目前队列已空,等待入值中");
notEmpty.await();
}
if (head > (nodes.length - 1)) { // 若取值游标大于游标最大值,则从0开始计算
head = 0;
}
t = nodes[head]; // 拿到元素值
nodes[head] = null; // 清空原有位置上的值
head++; // 取值游标+1
count--; // 元素个数-1
notFull.signalAll(); // 走到这里说明队列至少有一个空位,则唤醒入值
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
} return t;
} }

以上为主要代码,下面进行简单的测试:


@Test
public void simpleQueueTest() throws Exception { executorService.execute(() -> {
simpleQueue.put(1);
simpleQueue.put(2);
simpleQueue.put(3);
simpleQueue.put(4);
simpleQueue.put(5);
simpleQueue.put(6); simpleQueue.put(7);
simpleQueue.put(8);
simpleQueue.put(9);
simpleQueue.put(10);
simpleQueue.put(11);
simpleQueue.put(12);
}); Thread.sleep(5000L); executorService.execute(() -> { Integer r;
while ((r = simpleQueue.take()) != null) {
System.out.println(r);
}
}); Thread.sleep(5000L);
}

运行结果:


目前队列已满,等待取值中
目前队列已满,等待取值中
1
2
目前队列已满,等待取值中
3
目前队列已满,等待取值中
4
5
6
7
8
9
目前队列已空,等待入值中
10
11
12
目前队列已空,等待入值中

利用ReentrantLock简单实现一个阻塞队列的更多相关文章

  1. 进阶高阶IoT架构-教你如何简单实现一个消息队列

    前言 消息队列是软件系统领域用来实现系统间通信最广泛的中间件.基于消息队列的方式是指由应用中的某个系统负责发送消息,由关心这条消息的相关系统负责接收消息,并在收到消息后进行各自系统内的业务处理.消息可 ...

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

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

  3. 使用 ReentrantLock 和 Condition 实现一个阻塞队列

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

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

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

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

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

  6. 利用jdbc简单封装一个小框架(类似DBUtils)

    利用jdbc写的一个类似DBUtils的框架 package com.jdbc.orm.dbutils; import java.io.IOException; import java.io.Inpu ...

  7. 利用Bootstrap简单实现一个文件上传进度条

    © 版权声明:本文为博主原创文章,转载请注明出处 说明: 1. 使用commons-fileupload.jar实现文件上传及进度监听 2. 使用bootstrap的进度条进行页面显示 3. 因为进度 ...

  8. 阻塞队列 - java基于链表的简单实现

    1.阻塞队列的原理 阻塞队列与普通队列的区别在于:阻塞队列为空时,从队列中获取元素的操作将会被阻塞,当队列为满时,往队列里添加元素的操作会被阻塞. 试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其 ...

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

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

随机推荐

  1. 关于GLSL中语法和调用规则的一些记录

    glsl是什么就不多说了.这里只介绍一下glsl中一些限定符. glsl中包含两类具有定义性质的符号,一类是和c++中定义变量的一样的符号,用来说明存放数据的类型,如float,int,bool.还有 ...

  2. W-D-S-链接地址

    1.程序一开始是烧写到nandflash上,设置为nandflash启动,6410片内有8K的内存,设为nandflash启动时,是从片内内存0地址开始,一上电,nandflash前面8K的内容会原原 ...

  3. 搭建jfinal框架时报 Could not load driverClass com.mysql.jdbc.Driver

    搭建jfinal框架时报 Could not load driverClass com.mysql.jdbc.Driver 没有加载MySQL的驱动,你有没有把mysql的驱动包放到你项目的WEB-I ...

  4. WebAPI请求(转)

    出处:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...

  5. 使用WindowsFormsApplicationBase实现引导界面

    1.需要添加对Microsoft.VisualBasic 引用, 2.准备frmMain,frmSplash两个窗口 说明:        frmSplash在主线程上建立,但是在独立线程上进行消息循 ...

  6. (转)【javascript基础】原型与原型链

    原文地址:http://www.cnblogs.com/allenxing/p/3527654.html 前言 原型是什么 理解原型对象 原型对象 isPrototypeOf hasOwnProper ...

  7. Java学习总结——常见问题及解决方法

    CYTX项目开发中遇到的问题及解决方法 Android开发各类常见错误解决方案: 使用Android Studio遇到的问题及解决过程 登录注册部分问题及解决: 1.问题:"No targe ...

  8. (广搜) Find a way -- hdu -- 2612

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 MS (Java/Others) ...

  9. [leetcode] 13. Remove Duplicates from Sorted List

    这个题目其实不难的,主要是我C++的水平太差了,链表那里绊了好久,但是又不像用python,所以还是强行上了. 题目如下: Given a sorted linked list, delete all ...

  10. php萌新|学习|排坑|のmysqli_error()方法的妙用

    从开始学习php当现在已经有一个月多.除了每天完成公司布置的日常汇报,也没有耐下性子写一写自己想写的东西.今天就当起个头,坚持一周有个两三片文章或者小总结,也不枉费自己的付出.(我自己都不信,你会信吗 ...