线程中volatile生成自动增长的唯一编号

用volatile生成自动唯一编号代码
public class OrderNoUtils {
	/**
	 * 时间格式化
	 */
	protected static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	
	/** 基金订单编号 */
	public volatile static AtomicInteger fdOrderNumber = new AtomicInteger();
	
	/** 生成当前基金订单编号的日期 */ 
	public volatile static String createNumberDate = null;
	
	/**
	 * 根据数据库中当天最大的订单编号,生成订单唯一编号值
	 * @param dbCurrentNumber:数据库当天最大订单编号,如果为空则从1开始
	 * @return
	 */
	public static String getFdOrderNumber(String dbCurrentNumber){
		// 获取系统当前时间
		String date = sdf.format(new Date());
		
		String number = null;
		// 当生产编号日期为空的情况
		if(StringUtils.isBlank(createNumberDate)){
			// 默认生成编号日期等于系统当前日期
			createNumberDate = date;
		}
		// 生成基金编号的时间和系统当前天不一致的情况,以新产生编号序号为主
		if(!createNumberDate.equals(date)){
			// 系统当前日期和最后一次产生编号日期不一致的情况
			// 判断数据库查询的日期和系统当前时间是否一致
			if(StringUtils.isNotBlank(dbCurrentNumber) && dbCurrentNumber.indexOf(date) != -1){
				// 数据库中的当前时间的编号有值的情况
				// 以数据库中的最大编号进行累加
				StringBuffer sb= new StringBuffer(dbCurrentNumber.trim());
				// 将已有编号进行反转后取得头部的5位
				String temp = sb.reverse().substring(0, 5);
				// 将头5位反转,得到数据库现在的最大数值
				temp = new StringBuffer(temp).reverse().toString();
				Integer currNum = Integer.parseInt(temp);
				// 以数据库为准
				fdOrderNumber = new AtomicInteger(currNum);
			}else {
				// 数据库没有值,或者数据库中的编号时间不等于当前时间的其他情况,则需要新产生编号
				fdOrderNumber = new AtomicInteger();
			}
		}else {
			// 系统当前日期和最后一次产生编号日期一致的情况,以延续当前编号为
			// 判断数据库查询的日期和系统当前时间是否一致
			if(StringUtils.isNotBlank(dbCurrentNumber) && dbCurrentNumber.indexOf(date) !=-1){
				// 系统最大编号时间和当前产生编号时间一致的情况,需要判断数据库的编号是否大于当前编号
				// 一致的情况,判断当前编号和数据库的编号谁最大。
				StringBuffer sb= new StringBuffer(dbCurrentNumber.trim());
				// 将已有编号进行反转后取得头部的5位
				String temp = sb.reverse().substring(0, 5);
				// 将头5位反转,得到数据库现在的最大数值
				temp = new StringBuffer(temp).reverse().toString();
				Integer currNum = Integer.parseInt(temp);
				// 当数据库比现在的编号值大的情况,以数据库为准
				if(currNum>fdOrderNumber.get()){
					fdOrderNumber = new AtomicInteger(currNum);
				}
			}
		}
		number = date+String.format("%05d", fdOrderNumber.incrementAndGet());
		createNumberDate = date;
		System.out.println(Thread.currentThread().getName()+"---->"+number);
		return number;
	}
	
	public static void main(String[] args) {
		final String dbCurrentNumber = "HJS2018052500031";
		for(int i=0;i<10;i++){
			new Thread("Thread " +String.format("%04d", i)){
				public void run(){
					for(int j =0;j<10;j++){
						getFdOrderNumber(dbCurrentNumber);
					}
				}
			}.start();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/www520507/article/details/80431332