zoukankan      html  css  js  c++  java
  • 唯一序列号生成,自測支持高并发,不支持集群

    序列号组成:前缀 + 日期 + 尾数 

    比如:ZC20140806000001

    总共两个组成:一个枚举类。一个静态生成器。另外须要设计自己主动任务每日凌晨或其它时间重置一次尾数。


    先上枚举类:

    package com.boxmeal.base.constant.common;
    
    import java.util.concurrent.atomic.AtomicInteger;
    /**
     * 序列号生成枚举
     * @author bling
     *
     */
    public enum SNEnum {
    
    	// 订单编号
    	SUIT("tcd",new AtomicInteger(0));
    	
    	private String prefix;
    	
    	private AtomicInteger count;
    	
    	private SNEnum(String prefix,AtomicInteger count) {
    		this.prefix = prefix;
    		this.count = count;
    	}
    
    	public void setPrefix(String prefix) {
    		this.prefix = prefix;
    	}
    
    	public void setCount(AtomicInteger count) {
    		this.count = count;
    	}
    
    	public String getPrefix() {
    		return prefix;
    	}
    
    	public AtomicInteger getCount() {
    		return count;
    	}
    }
    枚举类是为了控制參数保证统一性。


    再上生成器类:

    package com.boxmeal.base.util;
    
    import java.text.DecimalFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.atomic.AtomicInteger;
    
    import com.boxmeal.base.constant.common.SNEnum;
    
    /**
     * 序列号生成器,每日自己主动从1開始增长
     * @author bling
     *
     */
    public class SNGenerater {
    
    	/**
    	 * 日期格式化
    	 */
    	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
    	
    	/**
    	 * 数字格式化
    	 */
    	private static final DecimalFormat decimalFormat = new DecimalFormat("000000");
    	
    	/**
    	 * 序列号产生器
    	 * @param sn
    	 * @return
    	 */
    	public final static String genSuitSN(SNEnum sn){
    		String prefix = sn.getPrefix();
    		String dateStr = SNGenerater.dateFormat.format(new Date());
    		String suffix = SNGenerater.decimalFormat.format(sn.getCount().incrementAndGet());
    		return prefix + dateStr + suffix;
    	}
    	
    	/**
    	 * 重置序列号生成器:自己主动任务每日夜间00:00调用一次
    	 */
    	public final static void reset(){
    		SNEnum[] snEnumAry = SNEnum.values();
    		for(int i=0;i<snEnumAry.length;i++){
    			snEnumAry[i].setCount(new AtomicInteger(0));
    		}
    	}
    	
    	public static void main(String[] args) {
    		for(int i=0;i<100;i++){
    			System.out.println(SNGenerater.genSuitSN(SNEnum.SUIT));
    		}
    		SNGenerater.reset();
    		for(int i=0;i<100;i++){
    			System.out.println(SNGenerater.genSuitSN(SNEnum.SUIT));
    		}
    	}
    	
    }
    

    尽管在生成器方法没有加同步关键词,是由于尾数自增是原子操作。


    測试类:

    package com.boxmeal.test;
    
    import com.boxmeal.base.constant.common.SNEnum;
    import com.boxmeal.base.util.SNGenerater;
    
    public class SNTest {
    
    	class VisitThread implements Runnable{
    		
    		@Override
    		public void run() {
    			for(int i=0;i<100;i++){
    				System.out.println(SNGenerater.genSuitSN(SNEnum.SUIT));
    				try {
    					Thread.sleep(20);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    	
    	public void test(){
    		for(int i=0;i<20;i++){
    			new Thread(new VisitThread()).start();
    		}
    	}
    	
    	public static void main(String[] args) {
    		new SNTest().test();
    	}
    	
    }
    

    开了20个线程并发2000次訪问,測试结果没有发生反复。


  • 相关阅读:
    Redis基本数据结构总结之SET、ZSET和HASH
    C# .Net计算函数执行的时间
    千万级规模高性能、高并发的网络架构经验分享
    c#单元测试:使用Moq框架Mock对象
    spring bean的构造器参数
    Java并发编程:ThreadLocal
    redis过期策略
    JAVA线程的生命周期状态
    jdk1.8新特性之Optional
    对Java中interrupt、interrupted和isInterrupted的理解
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7233460.html
Copyright © 2011-2022 走看看