您的位置:首页 > 其它

唯一序列号生成,自测支持高并发,不支持集群

2014-08-06 17:02 323 查看
序列号组成:前缀 + 日期 + 尾数 

例如: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次访问,测试结果没有发生重复。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: