锁定老帖子 主题:一个循环流水号实现,求评
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (4)
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-17
最后修改:2011-09-17
/** * 流水号 */ private static volatile int serialNumber = 0; /** * 生成流水号 * 从1 - 999999,不足六位,从右往左补0 * @return */ public static synchronized String generateSerialNumber(){ int n = serialNumber = ++serialNumber; if(n == (999999 + 1)){ serialNumber = n = 1; } StringBuffer strbu = new StringBuffer(6); strbu.append(n); for(int i=0, length=6-strbu.length(); i<length; i++){ strbu.insert(0, 0); } return strbu.toString(); } 生成的数字测过,没问题,就是不知道这么写在多线程时靠不靠谱,当并发多大的时候,会出问题吗? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-09-18
方法的头一段可以改成:
int n = ++serialNumber; serialNumber %= 999999; 另外,你的程序不考虑系统重启的可能性么? |
|
返回顶楼 | |
发表时间:2011-09-19
流水号这东西需要持久化吧,只在内存里记录的话系统一重启就出问题了
|
|
返回顶楼 | |
发表时间:2011-09-19
什么情况下要生成循环的可重复流水号?
|
|
返回顶楼 | |
发表时间:2011-09-19
hareamao 写道 方法的头一段可以改成:
int n = ++serialNumber; serialNumber %= 999999; 另外,你的程序不考虑系统重启的可能性么? 小小纠正一下,按楼主要求,应该是 int n = serialNumber = serialNumber%999999 + 1; 应该是可以不同步整个方法的吧,n属于局部变量,只要同步serialNumber部分就可以了。 |
|
返回顶楼 | |
发表时间:2011-09-19
AnotherTomorrow 写道 hareamao 写道 方法的头一段可以改成:
int n = ++serialNumber; serialNumber %= 999999; 另外,你的程序不考虑系统重启的可能性么? 小小纠正一下,按楼主要求,应该是 int n = serialNumber = serialNumber%999999 + 1; 应该是可以不同步整个方法的吧,n属于局部变量,只要同步serialNumber部分就可以了。 有问题吧,这样一直加下去,不考虑int溢出吗? 整个操作过程 check - save - get 应该封装为原子操作,同时可以考虑使用jdk的原子变量类来简化过程 |
|
返回顶楼 | |
发表时间:2011-09-19
quxiaoyong 写道 什么情况下要生成循环的可重复流水号?
上峰的要求,小弟只管实现 |
|
返回顶楼 | |
发表时间:2011-09-19
Crusader 写道 AnotherTomorrow 写道 hareamao 写道 方法的头一段可以改成:
int n = ++serialNumber; serialNumber %= 999999; 另外,你的程序不考虑系统重启的可能性么? 小小纠正一下,按楼主要求,应该是 int n = serialNumber = serialNumber%999999 + 1; 应该是可以不同步整个方法的吧,n属于局部变量,只要同步serialNumber部分就可以了。 有问题吧,这样一直加下去,不考虑int溢出吗? 整个操作过程 check - save - get 应该封装为原子操作,同时可以考虑使用jdk的原子变量类来简化过程 因为到了999999就设为0,重新计数,系统重启没考虑了,小弟又修改了下,恳请各位大哥指导啊~ public class SerialNumber { private static SerialNumber instance = new SerialNumber(); public static SerialNumber getInstance(){ return SerialNumber.instance; } private SystemParamDAO systemParamDAO; /** * 流水号 */ private static volatile int serialNumber = 0; /** * 读取数据库中初始,或中断时记录的流水号 */ public void initSerialNumber() { SerialNumber.serialNumber = Integer.parseInt(this.systemParamDAO.search("serial_number")); } /** * 生成流水号 * 从1 - 999999,不足六位,从右往左补0 * @return */ public synchronized String generateSerialNumber(){ int n = serialNumber = ++serialNumber; if(n == (999999 + 1)){ serialNumber = n = 1; } SerialNumber.instance.systemParamDAO.updateBySerialNumber(n); StringBuffer strbu = new StringBuffer(6); strbu.append(n); for(int i=0, length=6-strbu.length(); i<length; i++){ strbu.insert(0, 0); } return strbu.toString(); } public void setSystemParamDAO(SystemParamDAO systemParamDAO) { this.systemParamDAO = systemParamDAO; } } |
|
返回顶楼 | |
发表时间:2011-09-19
最后修改:2011-09-19
单例实现跟你1楼的static实现没有什么区别。
initSerialNumber()什么时候调用?可以考虑放到static代码段中。 另外 for(int i=0, length=6-strbu.length(); i<length; i++){ strbu.insert(0, 0); } 这里性能不好。 |
|
返回顶楼 | |
发表时间:2011-09-19
一个sequence就搞定了,要这么麻烦?
|
|
返回顶楼 | |