zoukankan      html  css  js  c++  java
  • java并发下订单生成策略

    import java.time.Instant;
    import java.util.HashSet;
    import java.util.Random;
    import java.util.Set;
    import java.util.UUID;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.commons.lang3.time.FastDateFormat;
    
    /**
     * 创建订单编号
     * 
     * @project sorder
     * @fileName MakeCode.java
     * @Description
     * @author light-zhang
     * @date 2018年3月11日下午12:19:25
     * @version 1.0.0
     */
    public abstract class MakeCode {
        /**
         * 订单号生成计数器
         */
        private static long orderNumCount = 0L;
        /**
         * 每毫秒生成订单号数量最大峰值
         */
        private static final int maxPerMSECSize = 2000;
        private static final String[] machine = new String[] { "00100", "00200", "00300", "00400" };// 这个很重要,如果是分配的不同机器,随机分配机器编码要不一致
        private static final FastDateFormat date_pattern = FastDateFormat.getInstance("yyyyMMdd");
        private static final FastDateFormat seconds_pattern = FastDateFormat.getInstance("HHmmss");
    
        /**
         * 并发下面容易产生重复的订单号,给传入的PKID枷锁,保证资源安全的同时,性能也有所下降 订单生成策略为: 时间20180511
         * +机器编码(我这里临时填写的是00100),在本台机器上生成订单编号的标识,如果分开部署,则此处的机器码需要变更,防止出现意外重复 +二位随机数
         * +lock的hash-code编码,这里有个并发下的性能问题 +时间时分秒 +递增参数值
         * 
         * @param lock
         *            生成的UUID32位参数
         * @return
         */
        public static String makeOrderCode(String lock) {
            final StringBuilder builder = new StringBuilder(35);
            synchronized (lock) {// 锁住传入的lock[UUID]
                if (orderNumCount >= maxPerMSECSize) { // 计数器到最大值归零,目前1毫秒处理峰值2000个
                    orderNumCount = 0L;
                }
                orderNumCount++;
                builder.append(date_pattern.format(Instant.now().toEpochMilli()));// 取系统当前时间作为订单号变量前半部分
                builder.append(machine[getMachine()]);// 当前服务机器分配的随机码
                builder.append(getNumber());// 随机数
                builder.append(Math.abs(lock.hashCode()));// HASH-CODE
                builder.append(seconds_pattern.format(Instant.now().toEpochMilli())); // 获取毫秒产生参数
                builder.append(orderNumCount);// 计数器的值
                return builder.toString();
            }
        }
    
        /**
         * 产生随机的2位数
         * 
         * @return
         */
        public static String getNumber() {
            final Random rad = new Random();
            String result = Integer.toString(rad.nextInt(100));
            if (Integer.compare(result.length(), 1) == 0) {
                result = "0".concat(result);
            }
            return result;
        }
    
        /**
         * 随机抽取机器码
         * 
         * @return
         */
        public static int getMachine() {
            final Random rad = new Random();
            return rad.nextInt(machine.length);
        }
    
        public static void main(String[] args) {
            Set<String> set = new HashSet<String>();
            for (int i = 0; i < 100; i++) {
                set.add(makeOrderCode(StringUtils.replace(UUID.randomUUID().toString(), "-", "")));
            }
            System.out.println(set.size());
        }
    }
  • 相关阅读:
    Openwrt单独编译某一个模块而不是整个固件
    在ubuntu 14.04 编译android 2.3.1 错误解决办法
    使用cydia substrate 来进行android native hook
    使用Privoxy转化SSH到HTTP代理
    使用xposed 来解阿里ctf-2014 第三题
    一个android dex 转java源码工具
    git CVE-2014-9390 验证以及源码对比
    一键结束port 5037占用
    运动物体检测——光流法(摄像机固定)
    运动目标检测ViBe算法
  • 原文地址:https://www.cnblogs.com/light-zhang/p/9024603.html
Copyright © 2011-2022 走看看