" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

引言

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

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

2. uuid 這個號稱是全球唯一的,但是無序,沒有實際意義,只能保證唯一

3. 時間戳,這種在分布式的場景下就需要考慮更多種情況

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

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

工具類

@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)前:(年、月、日、時、分、秒、毫秒)
        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)前時間,精確到毫秒級,如果有需要的話可以在實例化timeCount的時候乘以10或者100 1000之類的,這個看大家,然后加上鎖,防止線程不安全的情況,加鎖失敗的時候遞歸,再來一次。

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

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

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

測試

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ù)請求
                try {
                    list.add(NumUtil.nextPkId());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                latch.countDown();
            });
        }
        try {
            // 一定記得加上timeout時間,防止阻塞主線程
            latch.await(3000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }
        //4.等待所有子任務(wù)完成,組裝內(nèi)容
        while (list.size() < n) {
            log.info("集合長度 >>> {}",list.size());
        }
        //5.關(guān)閉線程池
        executorService.shutdown();

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

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

結(jié)論

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

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

相關(guān)文章

  • SpringBoot使用itext填充pdf表單及導(dǎo)出pdf的流程

    SpringBoot使用itext填充pdf表單及導(dǎo)出pdf的流程

    由于最近開發(fā)的項目需要用到打印單據(jù),就在網(wǎng)上找了一下方案,反反復(fù)復(fù),都沒有找到合適的,借鑒了網(wǎng)上資源,使用itext5、itext7的工具包,所以本文介紹了SpringBoot使用itext填充pdf表單及導(dǎo)出pdf的流程,需要的朋友可以參考下
    2024-09-09
  • Java分布式session存儲解決方案圖解

    Java分布式session存儲解決方案圖解

    這篇文章主要介紹了Java分布式session存儲解決方案圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • 詳解java定時任務(wù)

    詳解java定時任務(wù)

    這篇文章主要為大家詳細(xì)介紹了java定時任務(wù),使用JDK中的Timer定時任務(wù)來實現(xiàn),感興趣的小伙伴們可以參考一下
    2016-03-03
  • Java多線程案例實戰(zhàn)之定時器的實現(xiàn)

    Java多線程案例實戰(zhàn)之定時器的實現(xiàn)

    在Java中可以使用多線程和定時器來實現(xiàn)定時任務(wù),下面這篇文章主要給大家介紹了關(guān)于Java多線程案例之定時器實現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Java預(yù)防SQL注入的具體實踐方法

    Java預(yù)防SQL注入的具體實踐方法

    在?Java?中預(yù)防?SQL?注入的核心是?避免直接拼接?SQL?語句,并通過參數(shù)化查詢、ORM?框架和嚴(yán)格的輸入驗證來實現(xiàn)安全防護,以下是具體實踐方法,感興趣的小伙伴跟著小編一起來看看吧
    2025-01-01
  • 將InputStream轉(zhuǎn)化為base64的實例

    將InputStream轉(zhuǎn)化為base64的實例

    這篇文章主要介紹了將InputStream轉(zhuǎn)化為base64的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot啟動失敗的原因及其解決方法

    SpringBoot啟動失敗的原因及其解決方法

    對于springboot的啟動失敗,相信大家都有經(jīng)歷,但是為什么會啟動失敗,以及怎么解決都只能通過日志進行查看,在這里,我會將常見的springboot啟動失敗的報錯一一展示,需要的朋友可以參考下
    2024-06-06
  • Java設(shè)計模式之觀察者模式(Observer模式)介紹

    Java設(shè)計模式之觀察者模式(Observer模式)介紹

    這篇文章主要介紹了Java設(shè)計模式之觀察者模式(Observer模式)介紹,Java深入到一定程度,就不可避免的碰到設(shè)計模式(design pattern)這一概念,了解設(shè)計模式,將使自己對java中的接口或抽象類應(yīng)用有更深的理解,需要的朋友可以參考下
    2015-03-03
  • Springboot+redis+Interceptor+自定義annotation實現(xiàn)接口自動冪等

    Springboot+redis+Interceptor+自定義annotation實現(xiàn)接口自動冪等

    本篇文章給大家介紹了使用springboot和攔截器、redis來優(yōu)雅的實現(xiàn)接口冪等,對于冪等在實際的開發(fā)過程中是十分重要的,因為一個接口可能會被無數(shù)的客戶端調(diào)用,如何保證其不影響后臺的業(yè)務(wù)處理,如何保證其只影響數(shù)據(jù)一次是非常重要的,感興趣的朋友跟隨小編一起看看吧
    2019-07-07
  • 詳解如何使用MyBatis簡化JDBC開發(fā)

    詳解如何使用MyBatis簡化JDBC開發(fā)

    JavaEE?企業(yè)級?Java?項目中的經(jīng)典三層架構(gòu)為表現(xiàn)層,業(yè)務(wù)層和持久層.MyBatis?對?JDBC?代碼進行了封裝,作為一款優(yōu)秀的持久層框架,專門用于簡化JDBC開發(fā).本文主要介紹一下如何使用MyBatis簡化JDBC開發(fā),需要的可以參考一下
    2023-01-01

最新評論