" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java如何根據(jù)時(shí)間戳生成有序ID

 更新時(shí)間:2024年04月15日 10:01:57   作者:紫金丨小飛俠  
這篇文章主要介紹了java如何根據(jù)時(shí)間戳生成有序ID問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

引言

我們常用的主鍵有這么幾種

1. 數(shù)據(jù)庫(kù)自增主鍵,比如mysql的autoincrement,這種插入快,但是識(shí)別度不高

2. uuid 這個(gè)號(hào)稱是全球唯一的,但是無(wú)序,沒(méi)有實(shí)際意義,只能保證唯一

3. 時(shí)間戳,這種在分布式的場(chǎng)景下就需要考慮更多種情況

4. 雪花算法 snow flake ,分布式全局唯一主鍵,很牛,但是我覺(jué)得用起來(lái)也挺麻煩哈哈哈

所以在并發(fā)情況沒(méi)那么大的時(shí)候用一個(gè)工具類(lèi)搞定,我就是這么懶

工具類(lèi)

@Slf4j
public class NumUtil {

    private static long tmpID = 0;
    private static final long LOCK_TIME = 1;
    private static final long INCREASE_STEP = 1;
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
    private static final Lock LOCK = new ReentrantLock();


    public static long nextPkId() throws InterruptedException {
        //當(dāng)前:(年、月、日、時(shí)、分、秒、毫秒)
        long timeCount;
        if (LOCK.tryLock(LOCK_TIME, TimeUnit.SECONDS)) {
            timeCount = Long.parseLong(sdf.format(new Date()));
            try {
                if (tmpID < timeCount) {
                    tmpID = timeCount;
                } else {
                    tmpID += INCREASE_STEP;
                    timeCount = tmpID;
                }
                return timeCount;
            } finally {
                LOCK.unlock();
            }
        } else {
            log.error("lock failed");
            return nextPkId();

        }
    }
}

貼上代碼,這里用了當(dāng)前時(shí)間,精確到毫秒級(jí),如果有需要的話可以在實(shí)例化timeCount的時(shí)候乘以10或者100 1000之類(lèi)的,這個(gè)看大家,然后加上鎖,防止線程不安全的情況,加鎖失敗的時(shí)候遞歸,再來(lái)一次。

也可以使用synchronized做成同步方法,當(dāng)中的區(qū)別下次再討論。

有評(píng)論說(shuō)宕機(jī)會(huì)導(dǎo)致tmpID歸0導(dǎo)致已經(jīng)使用過(guò)超出當(dāng)前時(shí)間的ID,所以持久化這個(gè)tmpID也是可以的。

但這也就是在并發(fā)沒(méi)那么高的情況下才使用這種方法,一般并發(fā)場(chǎng)景下還是分布式鎖+推特的雪花算法解決。

測(cè)試

public static void numTest() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        int n = 10000;
        List<Long> list = new ArrayList<>();
        CountDownLatch latch = new CountDownLatch(n);
        for (int i = 0; i < n; i++) {
            executorService.execute(() -> {
                //執(zhí)行業(yè)務(wù)請(qǐng)求
                try {
                    list.add(NumUtil.nextPkId());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                latch.countDown();
            });
        }
        try {
            // 一定記得加上timeout時(shí)間,防止阻塞主線程
            latch.await(3000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }
        //4.等待所有子任務(wù)完成,組裝內(nèi)容
        while (list.size() < n) {
            log.info("集合長(zhǎng)度 >>> {}",list.size());
        }
        //5.關(guān)閉線程池
        executorService.shutdown();

        for (Long aLong : list) {
            System.out.println(aLong);
        }
    }

然后噼里啪啦打印了一萬(wàn)個(gè)ID,沒(méi)有重復(fù)的,一秒以內(nèi)生成

結(jié)論

當(dāng)然這種只是為了單體或者是并發(fā)沒(méi)有高到那么離譜的場(chǎng)景下使用,效率我覺(jué)得還不錯(cuò),分布式的場(chǎng)景下可能需要用到redis的自增來(lái)計(jì)數(shù)以達(dá)到數(shù)據(jù)安全的效果

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家

相關(guān)文章

  • 詳解 Java靜態(tài)代理

    詳解 Java靜態(tài)代理

    這篇文章主要介紹了 Java靜態(tài)代理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java代理的知識(shí),感興趣的朋友可以了解下
    2020-08-08
  • Java超詳細(xì)講解ArrayList與順序表的用法

    Java超詳細(xì)講解ArrayList與順序表的用法

    ArrayList 類(lèi)是一個(gè)可以動(dòng)態(tài)修改的數(shù)組,與普通數(shù)組的區(qū)別就是它是沒(méi)有固定大小的限制,我們可以添加或刪除元素。ArrayList 繼承了 AbstractList ,并實(shí)現(xiàn)了 List 接口,順序表是將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示
    2022-06-06
  • Spring Security獲取用戶認(rèn)證信息的實(shí)現(xiàn)流程

    Spring Security獲取用戶認(rèn)證信息的實(shí)現(xiàn)流程

    Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架。它提供了一組可以在Spring應(yīng)用上下文中配置的Bean,充分利用了Spring IoC,DI和AOP功能,為應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制功能
    2022-12-12
  • win10 eclipse配置環(huán)境變量的教程圖解

    win10 eclipse配置環(huán)境變量的教程圖解

    本文通過(guò)圖文并茂的形式給大家介紹了win10 eclipse配置環(huán)境變量的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-07-07
  • springboot @validated List校驗(yàn)失效問(wèn)題

    springboot @validated List校驗(yàn)失效問(wèn)題

    這篇文章主要介紹了springboot @validated List校驗(yàn)失效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • springboot動(dòng)態(tài)加載jar包動(dòng)態(tài)配置實(shí)例詳解

    springboot動(dòng)態(tài)加載jar包動(dòng)態(tài)配置實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于springboot動(dòng)態(tài)加載jar包動(dòng)態(tài)配置的相關(guān)資料,在項(xiàng)目開(kāi)發(fā)的過(guò)程中,有時(shí)候需要?jiǎng)討B(tài)靈活的加載某個(gè)jar包并執(zhí)行其里面的方法的時(shí)候,需要的朋友可以參考下
    2023-11-11
  • SpringBoot實(shí)現(xiàn)國(guó)際化的配置方法

    SpringBoot實(shí)現(xiàn)國(guó)際化的配置方法

    隨著一個(gè)系統(tǒng)的規(guī)模做上去之后,國(guó)際化的問(wèn)題就會(huì)逐漸暴露出來(lái),簡(jiǎn)單來(lái)說(shuō),當(dāng)你的系統(tǒng)面對(duì)的不再是本國(guó)的用戶,而要面臨海外用戶時(shí),系統(tǒng)必須要能適配國(guó)際化,所以本文給大家介紹了SpringBoot實(shí)現(xiàn)國(guó)際化的配置方法,需要的朋友可以參考下
    2025-11-11
  • Java利用OSHI實(shí)現(xiàn)獲取機(jī)器的硬件信息

    Java利用OSHI實(shí)現(xiàn)獲取機(jī)器的硬件信息

    OSHI(Operating System and Hardware Information)是一個(gè)開(kāi)源的Java庫(kù),用于獲取操作系統(tǒng)和硬件的詳細(xì)信息,下面我們就來(lái)看看他的具體使用吧
    2024-11-11
  • SpringCloud組件之Eureka Server詳細(xì)啟動(dòng)過(guò)程及說(shuō)明

    SpringCloud組件之Eureka Server詳細(xì)啟動(dòng)過(guò)程及說(shuō)明

    這篇文章主要介紹了SpringCloud組件之Eureka Server詳細(xì)啟動(dòng)過(guò)程及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • IDEA項(xiàng)目如何取消git版本管控并添加svn版本控制

    IDEA項(xiàng)目如何取消git版本管控并添加svn版本控制

    在公司內(nèi)部服務(wù)器環(huán)境下,將代碼倉(cāng)庫(kù)從Gitee的Git遷移到SVN可以避免外部版本控制的風(fēng)險(xiǎn),遷移過(guò)程中,先刪除項(xiàng)目的.git文件夾,再通過(guò)Eclipse的設(shè)置界面刪除原Git配置并添加SVN配置,之后,將項(xiàng)目提交到SVN倉(cāng)庫(kù),確保使用ignore列表過(guò)濾不必要的文件
    2024-10-10

最新評(píng)論

渭源县| 宜川县| 泾阳县| 定襄县| 凌海市| 清水河县| 潍坊市| 新兴县| 商洛市| 铜山县| 开江县| 濮阳市| 绥宁县| 新乡市| 宿迁市| 大厂| 贞丰县| 连城县| 报价| 海南省| 陆川县| 名山县| 正蓝旗| 汨罗市| 宁晋县| 梅州市| 开平市| 乳源| 布尔津县| 郧西县| 玛曲县| 金阳县| 长宁区| 蓝山县| 长白| 滨州市| 镶黄旗| 贵溪市| 大邑县| 亚东县| 裕民县|