java语言基于ArrayBlockingQueue 开发的一个根据特定前缀和后缀的队列。每天自动循环生成。

  1.定义队列基类 Cookie

  

package com.bytter.util.queue;

import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue; public class Cookie {
private ArrayBlockingQueue<String> queue;
private int cursor = 1;
private Date date = new Date();
private int maxPoolQueue = 500;
private int mixPoolQueue = 100; public Cookie(int maxPoolQueue,int mixPoolQueue,Date date){
this.maxPoolQueue=maxPoolQueue;
this.mixPoolQueue=mixPoolQueue;
this.date=date;
this.queue = new ArrayBlockingQueue<String>(this.maxPoolQueue,true);
} public Cookie(int maxPoolQueue,int mixPoolQueue,Date date, int cursor){
this.maxPoolQueue = maxPoolQueue;
this.mixPoolQueue = mixPoolQueue;
this.date=date;
this.cursor=cursor;
this.queue = new ArrayBlockingQueue<String>(this.maxPoolQueue,true);
} public ArrayBlockingQueue<String> getQueue() {
return queue;
} public Cookie setQueue(ArrayBlockingQueue<String> queue) {
this.queue = queue;
return this;
} public int getCursor() {
return cursor;
} public Cookie setCursor(int cursor) {
this.cursor = cursor;
return this;
} public Date getDate() {
return date;
} public Cookie setDate(Date date) {
this.date = date;
return this;
} public int getMaxPoolQueue() {
return maxPoolQueue;
} public Cookie setMaxPoolQueue(int maxPoolQueue) {
this.maxPoolQueue = maxPoolQueue;
return this;
} public int getMixPoolQueue() {
return mixPoolQueue;
} public Cookie setMixPoolQueue(int mixPoolQueue) {
this.mixPoolQueue = mixPoolQueue;
return this;
} }

  

  2.QueueUtil 队列工具类,用于获取队列中的值(主要是获取付款的单号==)

package com.bytter.util.queue;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import com.bytter.framework.persistence.dao.IBaseDAO;
import com.bytter.util.AppContextUtil;
import com.bytter.util.DateUtil;
/**
*
* @author
* May 6, 2019 10:35:39 AM
* @version
*/
public class QueueUtil{ private static Logger log = LogManager.getLogger(QueueUtil.class);
protected static IBaseDAO baseDao = null;
private static ConcurrentHashMap<String, Cookie> queueMap = new ConcurrentHashMap<String, Cookie>(); private static class SingletonClassInstance{
private static final QueueUtil instance=new QueueUtil();
} private QueueUtil(){} public static QueueUtil getInstance(){
return SingletonClassInstance.instance;
} /**
* 调用事例: QueueUtil.getInstance().getSequence(SequenceEnum.BIS_EXC)
* @param sequenceEnum
* @return
* @throws InterruptedException
*/
@SuppressWarnings("unchecked")
public String getSequence(SequenceEnum sequenceEnum) throws InterruptedException{
String value = "";
String key = sequenceEnum.getTableName()+"_"+sequenceEnum.getFieldName();
Cookie cookie = queueMap.get(key);
value = cookie.getQueue().take();
String returnValue = sequenceEnum.getPrefix()+DateUtil.dateToStr(sequenceEnum.getDateFormat(), new Date());
for (int i = 0; i < sequenceEnum.getSequenceLength()-value.length(); i++) {
returnValue += "0";
}
returnValue += value;
log.info("取出的单号:"+returnValue);
return returnValue;
} public void initQueue() {
putAllMap();
Thread thread = new Produce(queueMap);
thread.setName("QueueUtil_Produce");
thread.start();
} private static void putAllMap() {
queueMap.clear();
int curor = 1;
log.info("-----开始加载队列 -------");
for (SequenceEnum sequenceEnum : SequenceEnum.values()){
String key = sequenceEnum.getTableName()+"_"+sequenceEnum.getFieldName();
//同一天但是系统重启或者宕机的情况时,游标重置为1.此时需要查询表中最大的值并且置游标值+1
String sql="SELECT MAX("+sequenceEnum.getFieldName()+") FROM "+sequenceEnum.getTableName()+" WHERE "+sequenceEnum.getFieldName()+" LIKE '"+sequenceEnum.getPrefix()+"%'";
List list = baseDao.search_sql(null, sql, "", "", null);
if(list != null && list.size() >0 && list.get(0) != null){
String no = list.get(0).toString();
//单号,自增。
String count = no.substring(no.length()-sequenceEnum.getSequenceLength());
String date = no.replaceAll(count, "").replaceAll(sequenceEnum.getPrefix(), "");
/*if(date.equals(DateUtil.dateToStr(sequenceEnum.getDateFormat(), new Date()))){
curor = Integer.parseInt(count) + 1;
}*/
}
log.info("加载队列 :table=="+sequenceEnum.getTableName()+" field=="+sequenceEnum.getFieldName()+" 游标=="+curor);
queueMap.put(key, new Cookie(sequenceEnum.getMaxSeqSize(),sequenceEnum.getMinSeqSize(),new Date(),curor));
}
log.info("-----队列加载完毕 -------");
} static{
baseDao = AppContextUtil.getBean("baseDao");
//第一次调用时开启队列
//initQueue();
} }

  3.生产者线程类

  

package com.bytter.util.queue;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap; import com.bytter.util.DateUtil; public class Produce extends Thread{
private ConcurrentHashMap<String, Cookie> queueMap;
public Produce(ConcurrentHashMap<String, Cookie> queueMap){
this.queueMap=queueMap;
}
public void run(){
ArrayBlockingQueue<String> queue;
int mixSize;
int curor;
Cookie cookie;
Date date;
Map.Entry<String,Cookie> entry;
Iterator<Map.Entry<String,Cookie>> iteratorMap;
while (true) {
iteratorMap = queueMap.entrySet().iterator();
while (iteratorMap.hasNext()){
entry = iteratorMap.next();
cookie = entry.getValue();
queue = cookie.getQueue();
mixSize = cookie.getMixPoolQueue();
curor = cookie.getCursor();
date = cookie.getDate();
//新的一天,游标开始重置
if(!DateUtil.dateToStr("yyyy-MM-dd", new Date()).equals(DateUtil.dateToStr("yyyy-MM-dd", date))){
curor = 1;
queue.clear();
date = new Date();
System.out.println("重置游标时间===="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} //offer 在填满后返回false
if(queue.size() < mixSize){
while (queue.offer(curor + "")) {
curor++;
}
}
cookie.setQueue(queue).setCursor(curor).setDate(date);
queueMap.put(entry.getKey(),cookie);
}
}
}
}

  4.自定义的生成单号的规则枚举类

  

package com.bytter.util.queue;
public enum SequenceEnum{
/**
* 付款指令编码 yyMMdd000001
* @return
*/
BIS_EXC("",6, "BIS_EXC", "VOUCHER_NO", "yyMMdd",500,100),
/**
* 付款单号
* @return
*/
PAYMENT_BILL_NO("P",7, "T_BIS_PAYMENT_INFO", "BILL_CODE", "yyMMddHHmmss",500,100), ; /**
* 流水号前缀
*/
private String prefix; /**
* 流水号数字部分长度
*/
private Integer sequenceLength;
/**
* 业务表名
*/
private String tableName;
/**
* 业务表中的字段名
*/
private String fieldName;
/**
* 日期格式化模板
*/
private String dateFormat; /**
* 队列最大的长度
*/
private int maxSeqSize;
/**
* 队列最小长度
*/
private int minSeqSize; /**
* @param prefix 流水号前缀
* @param sequenceLength 流水号自增长长度
* @param tableName 表名
* @param fieldName 字段名
* @param dateFormat 日期格式化模板
*/
SequenceEnum(String prefix, Integer sequenceLength, String tableName, String fieldName,String dateFormat,int maxSeqSize,int minSeqSize) {
this.prefix = prefix;
this.sequenceLength = sequenceLength;
this.tableName = tableName;
this.fieldName = fieldName;
this.dateFormat = dateFormat;
this.maxSeqSize = maxSeqSize;
this.minSeqSize = minSeqSize;
} /**
* @param prefix 流水号前缀
* @param sequenceLength 流水号自增长长度
* @param tableName 表名
* @param fieldName 字段名
* @param dateFormat 日期格式化模板
*/
SequenceEnum(Integer sequenceLength, String tableName, String fieldName,String dateFormat) {
this.sequenceLength = sequenceLength;
this.tableName = tableName;
this.fieldName = fieldName;
this.dateFormat = dateFormat;
} public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public Integer getSequenceLength() {
return sequenceLength;
}
public void setSequenceLength(Integer sequenceLength) {
this.sequenceLength = sequenceLength;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
} public String getDateFormat() {
return dateFormat;
} public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
} public int getMaxSeqSize() {
return maxSeqSize;
} public void setMaxSeqSize(int maxSeqSize) {
this.maxSeqSize = maxSeqSize;
} public int getMinSeqSize() {
return minSeqSize;
} public void setMinSeqSize(int minSeqSize) {
this.minSeqSize = minSeqSize;
} }

  5.测试相关类

    1> 消费者线程

    

package com.bytter.util.queue;

public class 	 implements Runnable{

    public void run(){
try {
for (int i = 0; i < 200; i++) {
Thread.sleep(Long.valueOf((long) (Math.random()*10*300)));
// System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName()+"==="+SequenceUtilTest.getInstance().getSequence(SequenceEnum.BIS_EXC));
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}

    2>测试main 方法

package com.bytter.util.queue;

public class tests {

	public static void main(String[] args) throws InterruptedException {
new Thread(new Consume()).start();
new Thread(new Consume()).start();
new Thread(new Consume()).start();
new Thread(new Consume()).start();
new Thread(new Consume()).start();
// new Thread(new Consume()).start();
// new Thread(new Consume()).start();
// new Thread(new Consume()).start();
// new Thread(new Consume()).start();
// new Thread(new Consume()).start();
}
}

  

基于数组阻塞队列 ArrayBlockingQueue 的一个队列工具类的更多相关文章

  1. Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    Go/Python/Erlang编程语言对比分析及示例   本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...

  2. 编写Java程序,创建一个数学工具类,将该类设计为final类,Final 修饰符的使用。

    返回本章节 返回作业目录 需求说明: 创建一个数学工具类. 将该类设计为final类. 将该类的构造方法的访问权限定义为私有,以防止外界实例化该类. 在该类定义静态double类型常量π,其值为3.1 ...

  3. 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Caching; usi ...

  4. 分享一个Snackbar工具类 SnackbarUtils;

    分享一个Snackbar工具类,源代码也是在Github上面找的,自己做了一下修改: 功能如下: 1:设置Snackbar显示时间长短                 1.1:Snackbar.LEN ...

  5. java中定义一个CloneUtil 工具类

    其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...

  6. 手写一个LRU工具类

    LRU概述 LRU算法,即最近最少使用算法.其使用场景非常广泛,像我们日常用的手机的后台应用展示,软件的复制粘贴板等. 本文将基于算法思想手写一个具有LRU算法功能的Java工具类. 结构设计 在插入 ...

  7. [分享]一个String工具类,也许你的项目中会用得到

    每次做项目都会遇到字符串的处理,每次都会去写一个StringUtil,完成一些功能. 但其实每次要的功能都差不多: 1.判断类(包括NULL和空串.是否是空白字符串等) 2.默认值 3.去空白(tri ...

  8. 调用CMD命令的一个.NET工具类(MyWindowsCmd)

    功能大概描述一下如果直接StandardOutput.ReadToEnd()这种方法,有很多限制 这类方式必须把命令全部执行一次写入并标记为exit,而且返回内容的获取会一直等待,如果在主线程里使用会 ...

  9. 分享一个FileUtil工具类,基本满足web开发中的文件上传,单个文件下载,多个文件下载的需求

    获取该FileUtil工具类具体演示,公众号内回复fileutil20200501即可. package com.example.demo.util; import javax.servlet.htt ...

随机推荐

  1. pgsql物理复制(pgsql 备库的搭建以及角色互换,提升)

    结构图如下: Postgresql早在9.0版本开始支持物理复制,也称为流复制,通过从实例级复制出一个与主库一模一样的备库.流复制同步方式有同步,异步两种,如果主节点和备节点不是很忙,通常异步模式下备 ...

  2. HTTPS到底是什么

    Http存在的问题   上过网的朋友都知道,网络是非常不安全的.尤其是公共场所很多免费的wifi,或许只是攻击者的一个诱饵.还有大家平时喜欢用的万能钥匙,等等.那我们平时上网可能会存在哪些风险呢?   ...

  3. Bootstrap4中栅格系统CSS中 col-sm-* col-md-* col-lg-*的意义以及当其同时具有col-xs-* col-sm-* col-md-* col-lg-*的含义

    根据Bootstrap--Grid 中 col-sm-* col-md-* col-lg-* col-xl-*的意义: .col-sm-* 小屏幕 手机 (≥ 576px) .col-md-* 中等屏 ...

  4. vue-注册全局过滤器

    import Vue from 'vue'; import dayjs from 'dayjs'; const filters = { formatDate(date, format = 'YYYY- ...

  5. 传输层协议之TCP/UDP

    1.UDP UDP协议是面向无连接的,即不需要在正式传递数据前先链接双方,UDP协议只是数据报文的搬运工,不保证有序且不丢失的传递到对端,且UDP协议无任何控制流量的算法,UDP相对于TCP更加轻便. ...

  6. js 性能优化 - web worker

    当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能. 您可以继续做任何愿意做的事 ...

  7. RHEL6 中/etc/fstab文件解析

    1.系统环境 [root@natsha ~]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 6.5 (Santiag ...

  8. 基于vue模块化开发后台系统——准备工作

    文章目录如下:项目效果预览地址项目开源代码基于vue模块化开发后台系统--准备工作基于vue模块化开发后台系统--构建项目基于vue模块化开发后台系统--权限控制 前言 本文章是以学习为主,练习一下v ...

  9. vs2017 mvc 启动时经常出现调用的目标发生异常

    1.vs  2017 调试web 程序时老是出现调用的目标发生异常 本人眼拙,基本上看了网站说的一些方法,设置环境变量是无效的,只有一个办法,卸载重装. 1.0 卸载过程 打开计算机-卸载或更改软件- ...

  10. UVA-10480-Sabotage(最大流最小割,打印路径)

    链接: https://vjudge.net/problem/UVA-10480 题意: The regime of a small but wealthy dictatorship has been ...