欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

序列号生成器

程序员文章站 2022-06-19 19:23:44
...
/**
 * 生成序列号,最大值为MAX_VAL。如果达到MAX_VAL,从0开始。
 */
public class SerialGenerator {
    
    public static final int MAX_VAL = 999;
    public static final int R_NUM = getRNum(MAX_VAL);

    private static AtomicReference<AtomicInteger> ref = new AtomicReference<AtomicInteger>(new AtomicInteger(0));
    
    public static int getSerialNo() {
        AtomicInteger old = ref.get();
        int serialNo = old.getAndIncrement();
        while (serialNo > MAX_VAL) {
            AtomicInteger update = new AtomicInteger(0);
            ref.compareAndSet(old, update);
            old = ref.get();
            serialNo = old.getAndIncrement();
        }
        
        return serialNo;
    }
    
    /**
     * 求整数有几位,如234是3位。
     * @param i
     * @return
     */
    private static final int getRNum(int i) {
        if (i < 0) {
            throw new RuntimeException("Illegal arg i, i=" + i);
        }
        
        int div = i;
        int num = 1;
        div /= 10;
        while (div > 0) {
            div /= 10;
            num++;
        }
        
        return num;
    }
    
    /**
     * 获取序列号,该序列号为字符串表示,长度固定为序列号的最大长度,
     * 如果长度不足,则在前面补0,比如"015"
     * @return
     */
    public static String getSerialNoInStr() {
        int serialNo = getSerialNo();
        int rnum = getRNum(serialNo);
        
        StringBuilder sb = new StringBuilder();
        for (int i=0; i<R_NUM-rnum; i++) {
            sb.append("0");
        }
        
        return sb.append(serialNo).toString();
    }
    
    @Test
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //测10次
        for (int t=0; t<10; t++) {
            int taskNum = 1 + new Random().nextInt(19);
            @SuppressWarnings("unchecked")
            Future<Integer>[] fs = new Future[taskNum];
//            System.err.println(taskNum);
            ExecutorService executor = Executors.newFixedThreadPool(taskNum);
            for (int i=0; i<taskNum; i++) {
                fs[i] = executor.submit(new Callable<Integer>() {
                    int sum = 0;
                    @Override
                    public Integer call() throws Exception {
                        for (int i=0; i<=MAX_VAL; i++) {
                            sum += getSerialNo();
                        }
                        
                        return new Integer(sum);
                    } 
                });
            }
            
            int result = 0;
            for (Future<Integer> future : fs) {
                result += future.get();
            }
            
            int expect = 0;
            for (int i=0; i<taskNum; i++) {
                for (int j=0; j<=MAX_VAL; j++) {
                    expect += j;
                }
            }
            Assert.assertEquals(expect, result);
            System.out.println(taskNum + " : " + expect);
        }
        
        Random random = new Random();
        for (int i=0; i<10000; i++) {
            getSerialNoInStr();
            if (random.nextInt(1000) < 9) {
                System.out.println(getSerialNoInStr());
            } 
        } 
    }
    
}