使用了ConcurrentLinkedQueue,ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。它采用了“wait-free”算法来实现,该算法在Michael & Scott算法上进行了一些修改, Michael & Scott算法的详细信息可以参见参考资料一。
关于ConcurrentLinkedQueue详情:http://ifeve.com/concurrentlinkedqueue/
package util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import play.Configuration;
public class OrderNumberGenerator {
private static final ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
private static final CountDownLatch latch = new CountDownLatch(1);
/** * 每毫秒生成订单号数量最大值,约定取整百,整千。 */
public static final int maxPerMSECSize = Configuration.root().getInt("maxPerMSECSize", 1000);
private static void init() {
for (int i = 0; i < maxPerMSECSize; i++) {
queue.offer(i);
}
latch.countDown();
}
public static Integer poll() {
try {
if (latch.getCount() > 0) {
init();
latch.await(1, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Integer i = queue.poll();
queue.offer(i);
return i;
}
public static String get() {
long nowLong = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
String number = maxPerMSECSize + poll() + "";
return nowLong + number.substring(1);
}
}