Java订单号生成工具(实现二)基于队列

使用了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);
    }
}
展开阅读全文

没有更多推荐了,返回首页