Java并发生成不重复订单流水号

Posted kujo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发生成不重复订单流水号相关的知识,希望对你有一定的参考价值。

最近做一个订单模块要生成订单号,因为考虑到用mysql主键做订单号在以后分库分表后会重复,就想到自己创建。

这里要涉及到并发操作,所以要么就用单例内部类,或者就是加锁,因为时间关系我先实现了内部类和锁,后续再用类把String替换了。

具体代码:

package com.jzg.svsp.order.utils;

import javax.validation.constraints.NotNull;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * @author: YuGenHai
 * @name: AbstractOrderSequenceRandom
 * @creation: 2018/9/21 16:57
 * @notes: svsp + yyyyMMdd + uuid /random
 * @notes: 生成订单号工具类
 */
public abstract class AbstractOrderSequenceRandom {

    /**
     * 订单前缀
     */
    private static final String ORDERPREFIX = "SVSP";
    /**
     * 时间戳
     */
    private static final String FORMAT = "yyyyMMddHHmmss";
    /**
     * 数字随机
     */
    public static final String numberChar = "0123456789";

    /**
     * 随机数字
     */
    public static final int numberFor = 5;

    /**
     * @return
     * @author yugenhai
     */
    @NotNull
    public synchronized static String createOrderSnRandom() {
        return AbstractOrderSequenceRandomInner.createOrderSnRandomInner();
    }

    /**
     * 创建订单号<svsp + yyyy-mm-dd + Random>
     *
     * @author yugenhai
     */
    private final static class AbstractOrderSequenceRandomInner {
        private synchronized static String createOrderSnRandomInner() {
            SimpleDateFormat sdf = new SimpleDateFormat(FORMAT);
            StringBuffer sb = new StringBuffer();
            Random random = new Random();
            for (int i = 0; i < numberFor; i++) {
                sb.append(numberChar.charAt(random.nextInt(numberChar.length())));
            }
            return ORDERPREFIX + sdf.format(new Date()) + sb.toString();
        }
    }
}

 

之前没加锁时候如果在几个线程池里放了几百个线程同时生成的情况下是有极小的几率会重复,因为还没有做成单例类返回原因,加了锁初步可以上线,后续在调整。

 

以上是关于Java并发生成不重复订单流水号的主要内容,如果未能解决你的问题,请参考以下文章

生成订单编号 用java怎么处理

交易系统核心

13位纯数字订单号生成 - java

如何生成唯一订单号

干货分享:五分钟教你解决高并发场景下的订单和库存处理方案

java实现自动生成流水号的方法?