利用ReentrantLock简单实现一个阻塞队列
借助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简单实现一个阻塞队列的更多相关文章
- 进阶高阶IoT架构-教你如何简单实现一个消息队列
前言 消息队列是软件系统领域用来实现系统间通信最广泛的中间件.基于消息队列的方式是指由应用中的某个系统负责发送消息,由关心这条消息的相关系统负责接收消息,并在收到消息后进行各自系统内的业务处理.消息可 ...
- 用Java如何设计一个阻塞队列,然后说说ArrayBlockingQueue和LinkedBlockingQueue
前言 用Java如何设计一个阻塞队列,这个问题是在面滴滴的时候被问到的.当时确实没回答好,只是说了用个List,然后消费者再用个死循环一直去监控list的是否有值,有值的话就处理List里面的内容.回 ...
- 使用 ReentrantLock 和 Condition 实现一个阻塞队列
前言 从之前的阻塞队列的源码分析中,我们知道,JDK 中的阻塞队列是使用 ReentrantLock 和 Condition 实现了,我们今天来个简易版的.代码如下: 代码 public class ...
- 16_Queue_利用wait()和notify()编写一个阻塞队列
[线程间通信概念] 线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体必用方式之一.当线程存在通信指挥,线程间的交互性会更强大,在提高CPU利用率的同 ...
- 浅谈Java中的Condition条件队列,手摸手带你实现一个阻塞队列!
条件队列是什么?可能很多人和我一样答不出来,不过今天终于搞清楚了! 什么是条件队列 条件队列:当某个线程调用了wait方法,或者通过Condition对象调用了await相关方法,线程就会进入阻塞状态 ...
- 利用jdbc简单封装一个小框架(类似DBUtils)
利用jdbc写的一个类似DBUtils的框架 package com.jdbc.orm.dbutils; import java.io.IOException; import java.io.Inpu ...
- 利用Bootstrap简单实现一个文件上传进度条
© 版权声明:本文为博主原创文章,转载请注明出处 说明: 1. 使用commons-fileupload.jar实现文件上传及进度监听 2. 使用bootstrap的进度条进行页面显示 3. 因为进度 ...
- 阻塞队列 - java基于链表的简单实现
1.阻塞队列的原理 阻塞队列与普通队列的区别在于:阻塞队列为空时,从队列中获取元素的操作将会被阻塞,当队列为满时,往队列里添加元素的操作会被阻塞. 试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其 ...
- 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?
多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...
随机推荐
- loadrunner12: Error -27492: "HttpSendRequest" failed, Windows error code=8
这个问题我在网上看到有这样的解释:1.timeout时间超时设置问题2.Run-Time Settings -> Preferences -> Advanced. 确定此选项未被选中:&q ...
- Workflow笔记2——状态机工作流(转)
出处:http://www.cnblogs.com/jiekzou/p/6192813.html 在上一节Workflow笔记1——工作流介绍中,介绍的是流程图工作流,后来微软又推出了状态机工作流,它 ...
- IndexedDB:浏览器里内置的数据库(转)
出处;http://www.webhek.com/indexeddb/ IndexedDB是HTML5规范里新出现的浏览器里内置的数据库.对于在浏览器里存储数据,你可以使用cookies或local ...
- bean 的各个属性
http://www.springframework.org/schema/beans/spring-beans.xsd org.springframework.beans.factory.confi ...
- util:properties
示例 <util:properties id="db" location="classpath:db.properties" /> 全部属性 功能概 ...
- iOS7修改UISearchBar的Cancel按钮的颜色和文字
两行代码搞定: [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor ...
- alertView 上添加textField
- (void)showTextFieldUIAlertView { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@ ...
- 【StatLearn】统计学习中knn算法的实验(1)
Problem: Develop a k-NN classifier with Euclidean distance and simple voting Perform 5-fold cross va ...
- 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 ...
- sitecore 缓存管理器
namespace XXX.Shared.Infrastructure.Caching { using System; using System.Collections.Generic; using ...