zoukankan      html  css  js  c++  java
  • 15位自增ID生成工具类

    首先感谢https://blog.csdn.net/liuyanglglg/article/details/103480436作者的思路,然后进行了改进.

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import java.util.Random;

    /**
    * 15位自增CODE生成工具
    */
    public class SuperCodeUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(SuperCodeUtil.class);
    /**
    * 核销码表示字符,0~9,A~Z,去除0、O、I、L 4个易混淆的字符还是32位
    */
    private final static char[] DIGITS = {
    '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
    'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M',
    'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
    'Y', 'Z'};
    //时间戳位数,占9位
    private final static int STAMP_LEN = 9;
    //随机数位数,占4位
    private final static int RANDOM_LEN = 4;
    //随机数最大值
    private final static int MAX_RANDOM_INT = (int) (Math.pow(DIGITS.length, RANDOM_LEN) - 1);
    //上次时间戳值
    private static long last_Stmp = 0L;
    //随机对象
    private static final Random RANDOM = new Random();
    //同步锁对象
    private static Object lockObject = new Object();

    /**
    * 默认生成方法
    * 生成15位时间戳+随机数生成的编码
    *
    * @return
    */
    public static String genSuperCode() {
    return genSuperCode(0, 0);
    }

    /**
    * 生成15位时间戳+随机数生成的编码
    *
    * @param datacenterId 数据中心ID -1<datacenterId<DIGITS.length
    * @param machineId 机器ID -1<machineId<DIGITS.length
    * @return
    */
    public static String genSuperCode(int datacenterId, int machineId) {
    if (datacenterId > DIGITS.length - 1) datacenterId = 0;
    if (machineId > DIGITS.length - 1) machineId = 0;
    StringBuilder sbSuperCode = new StringBuilder();
    sbSuperCode.append(DIGITS[Math.abs(datacenterId)]);
    sbSuperCode.append(DIGITS[Math.abs(machineId)]);
    sbSuperCode.append(genStampCode());
    sbSuperCode.append(genRandomCode());
    return sbSuperCode.toString();
    }

    /**
    * 生成9位时间戳字符
    *
    * @return
    */
    private static String genStampCode() {
    long timestamp =System.currentTimeMillis();
    synchronized (lockObject)
    {
    while (timestamp <= last_Stmp) {
    try {
    //防止CPU占用过高
    lockObject.wait(10);
    } catch (InterruptedException e) {
    LOGGER.error("SuperCodeUtil ERROR:{}", e);
    }
    timestamp = System.currentTimeMillis();
    }
    last_Stmp = timestamp;
    }
    String stampCode = convert2String(timestamp);
    StringBuilder sb = new StringBuilder();
    //补齐位
    for (int i = stampCode.length(); i < STAMP_LEN; i++) {
    sb.append(DIGITS[0]);
    }
    return sb.toString() + stampCode;
    }

    /**
    * 生成4位随机数字符
    *
    * @return
    */
    private static String genRandomCode() {

    final int random = nextInt(0, MAX_RANDOM_INT);
    String randomCode = convert2String(random);
    StringBuilder sb = new StringBuilder();
    //补齐位
    for (int i = randomCode.length(); i < RANDOM_LEN; i++) {
    sb.append(DIGITS[0]);
    }
    return sb.toString() + randomCode;
    }

    /**
    * 把十进制转换成DIGITS.length定义的进制
    *
    * @param i
    * @return
    */
    private static String convert2String(long i) {
    char[] buf = new char[10];
    int charPos = 10 - 1;
    while (i > DIGITS.length - 1) {
    buf[charPos--] = DIGITS[(int) (i % DIGITS.length)];
    i /= DIGITS.length;
    }
    buf[charPos--] = DIGITS[(int) i];
    return new String(buf).trim();
    }

    /**
    * 根据范围生成随机数
    *
    * @param startInclusive
    * @param endExclusive
    * @return
    */
    private static int nextInt(int startInclusive, int endExclusive) {
    return startInclusive == endExclusive ? startInclusive : startInclusive + RANDOM.nextInt(endExclusive - startInclusive);
    }

    /*
    public static void main(String[] args) throws InterruptedException {
    List<String> list1= Lists.newArrayList();
    List<String> list2= Lists.newArrayList();
    Thread t1=new Thread(()->{
    for(int i=1000;i<1999;i++){
    list1.add(SuperCodeUtil.genSuperCode());
    }
    });
    Thread t2=new Thread(()->{
    for(int i=2000;i<2999;i++){
    list2.add(SuperCodeUtil.genSuperCode());
    }
    });
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(JSON.toJSONString(list1.stream().collect(Collectors.joining(","))));
    System.out.println(JSON.toJSONString(list2.stream().collect(Collectors.joining(","))));
    }
    */

    }
  • 相关阅读:
    进程池的使用
    同步提交,异步提交
    协程
    单线程下实现并发的套接字
    批量上传
    TP中的session和cookie
    ajaxReturn
    ajax的两种方式
    Yii里表单的操作方法(展示渲染待续......)
    Yii里文件上传的操作方法(图片修改,在详情上展示,批量上传待续...)
  • 原文地址:https://www.cnblogs.com/ff111/p/13969244.html
Copyright © 2011-2022 走看看