UUID生成方案

UUID組成部分

1+分片標(biāo)識(shí)符+年月日+遞增數(shù)字
其中遞增數(shù)字,長(zhǎng)度不夠前面補(bǔ)0

實(shí)現(xiàn)

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

public class UUIDGenerator {
    // 分片號(hào),占4位
    private static String slotId;
    // 是否調(diào)用init()方法進(jìn)行初始化
    private static boolean inited = false;

    private static int date;

    private static AtomicLong incre = new AtomicLong(1);
    private static final String DataFormat = "yyMMdd";
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>();

    private static DateFormat getDateFormat() {
        DateFormat df = threadLocal.get();
        if (df == null) {
            df = new SimpleDateFormat(DataFormat);
            threadLocal.set(df);
        }
        return df;
    }
    /**
     * 按指定格式對(duì)Date所持有的時(shí)間進(jìn)行格式化
     * @param date
     * @return
     */
    private static int format(Date date) {
        return Integer.valueOf(getDateFormat().format(date));
    }
    /**
     * 指定時(shí)間戳所在日期的0點(diǎn)時(shí)間戳
     * @param millis
     * @return
     */
    private static long zeroTime(long millis) {
        Calendar calendar = Calendar.getInstance();
        // TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
        // Calendar calendar = Calendar.getInstance(curTimeZone);

        calendar.setTimeInMillis(millis);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 在使用前調(diào)初始化
     * 
     * @param slotId
     */
    public static void init(int slotId) {
        if (inited) {
            return;
        }
        if (slotId >= 1000) {
            throw new RuntimeException("Slot ID must be smaller than 10000");
        }
        UUIDGenerator.slotId = String.format("%03d", slotId);
        inited = true;
    }
    /**
     * 生成UUID
     * @return
     */
    public static long generate() {
        if (!inited) {
            throw new RuntimeException("The init() method must be called first");
        }
        int currDate = format(new Date());

        if (currDate != date) {
            synchronized (UUIDGenerator.class) {
                if (currDate != date) {
                    //自增偏移量,初始值設(shè)置為當(dāng)日的秒數(shù),防止因重啟或其他原因造成生成的ID重復(fù)
                    long offset = 1+(System.currentTimeMillis() - zeroTime(System.currentTimeMillis()))/1000;
                    System.out.println("offset: "+offset);
                    incre.set(offset);
                    date = currDate;
                }
            }
        }
        String uuid = String.format("1%s%d%09d", slotId, date, incre.getAndIncrement());
        return Long.valueOf(uuid);
    }

    public static void main(String[] args) throws InterruptedException {
        UUIDGenerator.init(5);
        int jmax = 1000;
        CountDownLatch countDownLatch = new CountDownLatch(10);
        HashSet<Long> uuids = new HashSet<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < jmax; j++) {
                    long uuid = UUIDGenerator.generate();
                    System.out.println(uuid);
                    uuids.add(uuid);
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        if(uuids.size() != jmax*10) {
            System.out.println("UUID generate error ...... !!!");
        }else {
            System.out.println("UUID generate success!!!");
        }
    }
}

總結(jié)

每日可保存上億的UUID生成,足夠項(xiàng)目使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,436評(píng)論 6 13
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,666評(píng)論 1 32
  • JAVA UUID 生成 GUID是一個(gè)128位長(zhǎng)的數(shù)字,一般用16進(jìn)制表示。算法的核心思想是結(jié)合機(jī)器的網(wǎng)卡、當(dāng)?shù)?..
    藝龍閱讀 13,037評(píng)論 1 3
  • 原作者:http://blog.csdn.net/u014727709/article/details/72673...
    f9895fb9acee閱讀 1,587評(píng)論 0 10
  • “我是怎樣‘回看’自己的生命經(jīng)歷的。”這一講,我從張文質(zhì)老師似“嘮叨"又似"敘家常"的故事里看到自己,看到自...
    笑韻閱讀 295評(píng)論 0 0

友情鏈接更多精彩內(nèi)容