java 生成商品编号

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 商品编号
 * 
 * @作者 light-zhang
 * @时间 2018年10月30日
 * @product mall-utils
 * @package cc.zeelan.common.utils
 * @file GetKey.java
 *
 */
public final class GetKey {
    /**
     * 商品编号号生成计数器
     */
    private static long numberCount = 0L;
    /**
     * 每毫秒生成商品编号数量最大峰值
     */
    private static final int maxPerMSECSize = 20000;

    /**
     * 并发下面容易产生重复的订单号,给传入的PKID枷锁,保证资源安全的同时,性能也有所下降 订单生成策略为: 时间20180511
     * +机器编码(我这里临时填写的是00100),在本台机器上生成订单编号的标识,如果分开部署,则此处的机器码需要变更,防止出现意外重复 +二位随机数
     * +lock的hash-code编码,这里有个并发下的性能问题 +时间时分秒 +递增参数值
     * 
     * @param lock 生成的UUID32位参数
     * @return
     */
    public static String make() { 
        ReferenceQueue<StringBuilder> queue = new ReferenceQueue<StringBuilder>();
        WeakReference<StringBuilder> weakRef = new WeakReference<StringBuilder>(new StringBuilder(15), queue);
        synchronized (weakRef) {
            if (null == weakRef.get()) {
                weakRef = new WeakReference<StringBuilder>(new StringBuilder(15), queue);
            }
            if (numberCount >= maxPerMSECSize) { // 计数器到最大值归零,目前1毫秒处理峰值1个
                numberCount = 0L;
            }
            weakRef.get().append(Math.abs(UUID.randomUUID().toString().hashCode()));// HASH-CODE
            weakRef.get().append(numberCount++);// 计数器的值
            return weakRef.get().toString();
        }
    }

    /**
     * 100000个线程并发测试
     * 
     * @param args
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Set<String> set = new HashSet<String>();
        FutureTask<String> task = null; 
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // System.out.println("当前线程:>>>>> ".concat(Thread.currentThread().getName()));
                    return make();
                }
            };
            task = new FutureTask<String>(callable);
            new Thread(task).start();
         System.out.println("商品编号:>>>>> ".concat(task.get()));
            set.add(task.get());
        }
        System.out.println("总共耗时:" + ((System.currentTimeMillis() - startTime)) + "ms");
        System.out.println("*************** " + set.size());
    }
}

猜你喜欢

转载自www.cnblogs.com/light-zhang/p/9881359.html