订单编号的形成方法是不同的,有的是系统自动生成的,有的可以按照习惯遵循一定的规则编制,比如说今天是2015年8月2日,接的是第5个单,就可以把此订单编号为2015080200005.
实现订单号有很多种方法 :
1. 获取系统当前时间(精确到毫秒),加上用户ID作为一个唯一的订单编号
2.获取系统当前年月日加上随机数
3.获取系统当前年月日加上一定格式的号码(流水号每天从1开始)
4.获取系统当前年月日加上数据库序列号
5.使用时间搓
下面是我实现订单生产以及消费的过程,该方法需要在数据库新建一张表,专门来存放当tomact关闭时,把当天最后一个订单流水号送入数据库中。那么当当天的某一个时间启动服务时,从数据库中读取当天最后一个订单的的流水号读取出来,放入订单流水号 Map中,这样就可以避免tomact重启导致订单号重复。
private static OrderRunningNum instance;
//存放订单号的容器 订单号存放在list里,通过当天的日期来获取订单集合
private Map<String, List<String>> ordernums =new LinkedHashMap<String, List<String>>();
//存放订单流水号
private Map<String, Integer> map = new LinkedHashMap<String,Integer>();
//时间
private SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMdd");
//订单流水号长度
private int orderlength=5;
//私有的构造方法
private OrderRunningNum(){
}
/**
* 静态工厂方法,该对象只创建一次(单利模式)
* @return
*/
public synchronized static OrderRunningNum getInstance(){
if(instance==null){
instance = new OrderRunningNum();
}
return instance;
}
/**
* 得到最后的订单流水号
* @return
*/
public synchronized Integer getLastNum(){
Date data=new Date();
String nowdata=sdf.format(data);
return map.get(nowdata);
}
/**
* 存放最后的订单流水号
* @param num
*/
public synchronized void setLastNum(int num){
Date data=new Date();
String numdata=sdf.format(data);
map.put(numdata, num);
}
/**
* 得到订单号
* @return
*/
public String getOrderNum(){
String ordernum ="";
synchronized (this){
Date data =new Date();
String nowdata = sdf.format(data);
//得到当天的订单集合
List<String> list =ordernums.get(nowdata);
while (list ==null || list.size()==0 ){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ordernum = list.get(0);
list.remove(0);
this.notifyAll();
}
return ordernum;
}
/**
* 创建订单号
*/
public void createOrderNum(){
synchronized (this){
//现在的时间
Date now =new Date();
String nowdata=sdf.format(now);
//得到今天的订单
List<String> list =ordernums.get(nowdata);
//判断是是否有今天的订单,没有就创建一个空的订单集合
if(list == null){
list = new ArrayList<String>();
}
//得到今天最后的一个订单流水号
Integer lastOrder=map.get(nowdata);
//判断订单流水号是否为空
if(lastOrder == null){
lastOrder =0;
}
//流水号加 1
lastOrder = lastOrder+1;
String lastOrderstr=lastOrder + "";
String orderfinal =lastOrderstr;
//判断当前订单流水号的长度是否小于等于当前设置的订单流水号长度
if(lastOrderstr.length() <= orderlength){
//小于当前的订单流水号长度时,循环加0 ,直到等于当前设置的订单流水号长度
for(int i=0; i<orderlength - lastOrderstr.length();i++){
orderfinal ="0"+orderfinal;
}
}
//当天日期加上流水号,组成订单号
orderfinal = nowdata + orderfinal;
//把订单流水号放入map里
map.put(nowdata, lastOrder);
//把订单放入订单集合
list.add(orderfinal);
//把订单集合放入 map里
ordernums.put(nowdata, list);
while (list !=null && list.size()>5){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
}
}
public static void main(String[] args) {
final OrderRunningNum orderrunning= OrderRunningNum.getInstance();
orderrunning.setLastNum(0);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
orderrunning.createOrderNum();
}
}
}).start();
//创建一个现成池
ExecutorService exe =Executors.newFixedThreadPool(10);
for(int i=0;i<100;i++){
exe.execute(new Runnable() {
@Override
public void run() {
String ordernum=orderrunning.getOrderNum();
System.out.println(ordernum);
}
});
}
}
大家多多指教。