博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java订单编号工具类_[idmiss-common] Java 工具类之- 顺序订单号的生成
阅读量:6486 次
发布时间:2019-06-23

本文共 3084 字,大约阅读时间需要 10 分钟。

1.前言

这是我写的工具类之一:根据日期生成唯一顺序订单号。

用Java 配合 Redis 实现包含日期的顺序订单号的生成, 效率可以达到 2500+/s 1000W+/h 个 。

2.基本介绍

框架: Spring Boot

依赖: Redis

实现方式:生成订单号之前找到保存的最大ID值,并且设定过期时间(每天都从1开始生成);然后判断生成订单号队列里的订单号数量,如果达到阈值则生成新的一批订单号,如果没有达到阈值则直接返回订单号。

orderNoInitSize; //(order生成的速度)

orderNoCreateLength; //(需要重新生成的阈值)

orderLength; //(订单顺序号的位数 ,默认6位支持每天生成999999个订单号)

3.完整代码

@Override

public String getOrder(String type) {

DateFormat df = new SimpleDateFormat("yyyyMMdd");

String dayDf=df.format(new Date());

String orderKey=type.toString().concat("_").concat(dayDf);

if(getRedisSize(orderKey)<=orderNoCreateLength) {

this.generateInit(orderKey,type,dayDf);

}

return getOrderNo(orderKey);

}

//初始化

synchronized private void generateInit(String orderKey,String type,String dayDf) {

List orders=new ArrayList<>();

Long max=this.generate(orderKey.concat("_max"), 1, getTodayEndTime());

for(long i=max;i

orders.add(format(i,type.toString(),dayDf,orderLength));

}

redisTemplate.opsForList().leftPushAll(orderKey, orders);

redisTemplate.expireAt(orderKey, getTodayEndTime());

this.generate(orderKey.concat("_max"), orderNoInitSize-1, getTodayEndTime());

}

@SuppressWarnings("unused")

private String format(Long id,String prefix,String date,String minLength){

StringBuffer sb = new StringBuffer();

sb.append(prefix);

sb.append(date);

return sb.toString().concat(String.format("%1$0".concat(orderLength).concat("d"), id));

}

//通过key获取自增并设定过期时间

public Long generate(String key,Date expireTime) {

RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());

counter.expireAt(expireTime);

return counter.incrementAndGet();

}

//通过key获取增加的值 并设定过期时间

public long generate(String key,int increment,Date expireTime) {

RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());

counter.expireAt(expireTime);

return counter.addAndGet(increment);

}

// 获取当天过期时间

private Date getTodayEndTime() {

Calendar todayEnd = Calendar.getInstance();

todayEnd.set(Calendar.HOUR_OF_DAY, 23);

todayEnd.set(Calendar.MINUTE, 59);

todayEnd.set(Calendar.SECOND, 59);

todayEnd.set(Calendar.MILLISECOND, 999);

return todayEnd.getTime();

}

// 获取redis list size

private Long getRedisSize(String key) {

return redisTemplate.opsForList().size(key);

}

//获取订单号

private String getOrderNo(String key) {

return redisTemplate.opsForList().rightPop(key);

}

4.速度测试

Test 测试类,因机器配置不同执行时间会有差异

@Autowired

private OrderGenerateService orderGenerateService;

@Test

public void contextLoads() throws InterruptedException {

long startTime=System.currentTimeMillis();

ExecutorService executor=Executors.newFixedThreadPool(30);

for(int i=0;i<100000;i++) { executor.execute(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println(orderGenerateService.getOrder("PA")); } }); } while(true) { int threadCount = ((ThreadPoolExecutor)executor).getActiveCount(); if(threadCount>=30) {

Thread.sleep(10);

continue;

}

if(threadCount<=0) {

break;

}

}

long endTime=System.currentTimeMillis(); //获取结束时间

System.out.println("程序运行时间: "+(endTime-startTime)+"ms");

}

程序运行时间: 32423ms

5.完整代码

6.完成

转载地址:http://glnuo.baihongyu.com/

你可能感兴趣的文章
sorry,you must have a tty to run sudo
查看>>
ios开发中使用正则表达式识别处理字符串中的URL
查看>>
项目中的积累,及常见小问题
查看>>
Python类型转换、数值操作(收藏)
查看>>
oracle11g dataguard 安装手册(转)
查看>>
1. Two Sum - Easy - Leetcode解题报告
查看>>
多线程---同步函数的锁是this(转载)
查看>>
百练 2742 统计字符数 解题报告
查看>>
Ubuntu搜狗输入法候选词乱码
查看>>
js中回调函数写法
查看>>
React native android 最常见的10个问题
查看>>
数据结构和算法
查看>>
[pat]1045 Favorite Color Stripe
查看>>
Immutable学习及 React 中的实践
查看>>
【转】性能测试步骤
查看>>
OSI与TCP/IP各层的结构与功能,都有哪些协议
查看>>
Android实例-程序切换到后台及从后台切换到前台
查看>>
spring boot启动定时任务
查看>>
算法 (二分查找算法)
查看>>
java Date 当天时间戳处理
查看>>