借助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. Windows环境和Linux环境下Redis主从复制配置

    Windows环境下和Linux环境下配置Redis主从复制基本上一样,都是更改配置文件.Windows环境下修改的配置文件是:redis.windows.conf.redis.windows-ser ...

  2. winscp 使用root身份登录

    参考: https://www.haiyun.me/archives/winscp-sftp-sudo-root.html 一般root账户在服务器上会被禁止ssh,此时普通用户通过sudo执行管理员 ...

  3. SpringBoot里的一些注解

    Spring不仅可以通过xml配置获取*.properties,还可以通过@Value注解的方式来获取,将properties配置文件中的属性值注入到java成员变量. 如果不想每次都写private ...

  4. util:properties

    示例 <util:properties id="db" location="classpath:db.properties" /> 全部属性 功能概 ...

  5. CSS定位DIV(一)一列样式

    前记:CSS样式核心就是DIV布局,一些基础知识省略不记,接下来的日志只关注最核心的布局问题. 一.一列布局 1.固定宽高 直接声明宽高,或用百分比表示. width:400px; 或 width:7 ...

  6. zstu4273 玩具 2017-03-22 14:18 49人阅读 评论(0) 收藏

    4273: 玩具 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 700  Solved: 129 Description 商店有n个玩具,第i个玩具有 ...

  7. java程序无法启动:Unsupported major.minor version 51.0

    今天在sae上部署了一个项目,结果总是出现503错误:service unavailable,然后jvm出现了一大串错误日志,如下 JAVA_SAE_Fatal_error: Failed start ...

  8. struts2+ckeditor配置图片上传

    又是一个漫漫长夜. 公司的编辑器坏了,用的是百度编辑器,上传图片的网址被框架给拦截了,我们本地怎么测试都没问题,放到服务器就这样了.和老李找了半天,疯了,没原因的. 笔者以前用过jsp+ckedito ...

  9. sqlserver数据库存储汉字出现?

    问题:有些相对复杂的汉字在数据库里会变成? 解决办法:原来数据类型是varchar,将数据类型修改为nvarchar

  10. 【cocos2d-x 环境配置-Mac配置篇】

    目前我配置的环境需求如下: JDK 1.6 XCode Version 4.6 (4H127) Cocos2d-x 2.2.0  Android Developer  一,下载安装 要配置环境一次性下 ...