栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

java订单号生成算法

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java订单号生成算法

参考snowflake算法,基本思路:

序列12位(更格式化的输出后,性能损耗导致每毫秒生成不了这么多,所以可以考虑减少这里的位,不过留着也并无影响)

机器位10位

毫秒为左移 22位

上述几个做或运算后得出一个唯一的数,转10进制后,最大10位,最小7位,string.format来统一为10,format性能影响,导致性能降低3倍左右

FilUtils不想用的话,1太机器可以直接考虑使用1,多机器根据代码配置id

代码如下:

package net.gitosc.lianqu1990.utils.code;

import net.gitosc.lianqu1990.utils.date.DateFormatUtils;

import net.gitosc.lianqu1990.utils.date.TimeMark;

import org.apache.commons.io.FileUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.io.File;

public class OrderNoCenter {

public static final Logger logger = LoggerFactory.getLogger(OrderNoCenter.class);

private static final String WORKERID_PATH = "/etc/workerId";

private OrderNoCenter() {

}

private static class OrderNoCenterHolder{

private static OrderNoCenter instance = new OrderNoCenter();

}

public static OrderNoCenter getInstance() {

return OrderNoCenterHolder.instance;

}

private long workerId = 1;

private long sequence = 1;

private final long workerIdBits = 10L;

private final long maxWorkerId = -1L ^ (-1L << workerIdBits); //结果就是2的workerBits次方-1,能表示的最大数.全部1亦或10位0,就是0开头最后10位1

private final long sequenceBits = 12L;

private final long workerIdShift = sequenceBits;

private final long datacenterIdShift = sequenceBits + workerIdBits;

private final long sequenceMask = -1L ^ (-1L << sequenceBits);

private final long timestampLeftShift = sequenceBits + workerIdBits;

private long lastTimestamp = -1L;

public void initParam() {

// 从默认位置读取workerId,最大1024

try {

File conf = new File(WORKERID_PATH);

if(conf.exists()){

String str = FileUtils.readFileToString(conf);

workerId = Integer.parseInt(str);

}else{

logger.warn(" worker id not found,will use default value...");

}

} catch(Exception e){

e.printStackTrace();

}

logger.info(" worker id is {}",workerId);

if (workerId < 0 || workerId > maxWorkerId) {

throw new IllegalArgumentException("workerId is illegal: "

+ workerId);

}

}

public long getWorkerId() {

return workerId;

}

public long getTime() {

return System.currentTimeMillis();

}

public String create() {

return nextNo();

}

private synchronized String nextNo() {

long timestamp = timeGen();

// 时间错误

if (timestamp < lastTimestamp) {

throw new IllegalStateException("Clock moved backwards.");

}

// 当前毫秒内,则+1

if (lastTimestamp == timestamp) {

// 当前毫秒内计数满了,则等待下一秒

sequence = (sequence + 1) & sequenceMask;

if (sequence == 0) {

timestamp = tilNextMillis(lastTimestamp);

}

} else {

sequence = 0;

}

lastTimestamp = timestamp;

// ID偏移组合生成最终的ID,并返回ID,最大十位数

long id = ((timestamp % 1000) << timestampLeftShift) | (workerId << workerIdShift) | sequence;

String timestampStr = DateFormatUtils.NUMBER_FORMAT.format(timestamp);

return timestampStr+String.format("%010d",id);

}

private long tilNextMillis(long lastTimestamp) {

long timestamp = timeGen();

while (timestamp <= lastTimestamp) {

timestamp = timeGen();

}

return timestamp;

}

private long timeGen() {

return System.currentTimeMillis();

}

public static void main(String[] args){

for (int i = 0; i < 100; i++) {

System.out.println(OrderNoCenter.getInstance().create());

}

//性能测试

TimeMark mark = new TimeMark();

for (int i = 0; i < 1000000; i++) {

OrderNoCenter.getInstance().create();

}

mark.simplePrint();

mark.mark();

for (int i = 0; i < 1000000; i++) {

IdCenter.getInstance().getId();

}

mark.simplePrint();

}

}

缺少代码的话,请直接使用我的附件代码

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/985118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号