借助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. loadrunner12: Error -27492: "HttpSendRequest" failed, Windows error code=8

    这个问题我在网上看到有这样的解释:1.timeout时间超时设置问题2.Run-Time Settings -> Preferences -> Advanced. 确定此选项未被选中:&q ...

  2. Workflow笔记2——状态机工作流(转)

    出处:http://www.cnblogs.com/jiekzou/p/6192813.html 在上一节Workflow笔记1——工作流介绍中,介绍的是流程图工作流,后来微软又推出了状态机工作流,它 ...

  3. IndexedDB:浏览器里内置的数据库(转)

    出处;http://www.webhek.com/indexeddb/ IndexedDB是HTML5规范里新出现的浏览器里内置的数据库.对于在浏览器里存储数据,你可以使用cookies或local ...

  4. bean 的各个属性

    http://www.springframework.org/schema/beans/spring-beans.xsd org.springframework.beans.factory.confi ...

  5. util:properties

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

  6. iOS7修改UISearchBar的Cancel按钮的颜色和文字

    两行代码搞定: [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor ...

  7. alertView 上添加textField

    - (void)showTextFieldUIAlertView {     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@ ...

  8. 【StatLearn】统计学习中knn算法的实验(1)

    Problem: Develop a k-NN classifier with Euclidean distance and simple voting Perform 5-fold cross va ...

  9. An error "Host key verification failed" when you connect to other computer by OSX SSH

    Here's quick way to remove all entries in the host file: In an OSX terminal, type rm -f ~/.ssh/known ...

  10. sitecore 缓存管理器

    namespace XXX.Shared.Infrastructure.Caching { using System; using System.Collections.Generic; using ...