Java UUID會重複嗎?

一、UUID簡介

UUID(Universally Unique Identifier)是一種標識符,由一組32個十六進位數所構成,其理論上的唯一性是通過時間戳和隨機數來保證的。

Java中的UUID是通過java.util.UUID類來實現的,其主要有以下幾種方法:

    /**
     * 靜態方法,返回一個隨機生成的UUID。
     * @return 隨機生成的UUID
     */
    public static UUID randomUUID() {...}

    /**
     * 靜態方法,返回一個根據指定位元組數組生成的UUID。
     * @param input 位元組數組
     * @return 根據指定位元組數組生成的UUID
     */
    public static UUID nameUUIDFromBytes(byte[] input) {...}

    /**
     * 構造方法,根據指定的參數生成UUID
     * @param mostSigBits 64位的最高有效位
     * @param leastSigBits 64位的最低有效位
     */
    private UUID(long mostSigBits, long leastSigBits) {...}

二、UUID的唯一性

UUID的唯一性是通過時間戳和隨機數來保證的,其中時間戳的精度是100納秒,而隨機數則是通過SecureRandom類的實例生成的。因此,UUID的重複概率相當地小。

一方面從理論上講,如果一個系統每微秒生成一條UUID,那麼大約需要3.4×10^38年才能出現重複的UUID。另一方面,UUID的長度為128位,實際上是超過目前世界人口數量的。

因此,可以認為Java UUID幾乎是唯一的。不過,在實際應用中,我們仍然需要考慮UUID重複的情況。

三、UUID重複的情況

1.多線程環境下UUID重複

在多線程環境下,如果多個線程同時調用Java UUID的randomUUID()方法,那麼可能會出現UUID重複的情況。

為了避免這種情況,我們可以使用ThreadLocalRandom類代替SecureRandom類,即:

    UUID uuid = new UUID(ThreadLocalRandom.current().nextLong(), 
                         ThreadLocalRandom.current().nextLong());

2.分散式環境下UUID重複

在分散式環境下,如果多個節點同時生成UUID,那麼也會出現UUID重複的情況。

為了解決這個問題,我們可以使用第三方的UUID生成器,比如UUIDGenerator、Snowflake等。

下面是使用Snowflake演算法生成UUID的Java示例:

public class IdWorker {
    private long workerId;
    private long datacenterId;
    private long sequence = 0L;
    private long twepoch = 1288834974657L;
    private long workerIdBits = 5L;
    private long datacenterIdBits = 5L;
    private long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    private long sequenceBits = 12L;
    private long workerIdShift = sequenceBits;
    private long datacenterIdShift = sequenceBits + workerIdBits;
    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    private long sequenceMask = -1L ^ (-1L < maxWorkerId || workerId  maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId cannot be greater than " + maxDatacenterId + " or less than 0");
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();

        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }

        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = timestamp;

        return ((timestamp - twepoch) << timestampLeftShift) |
                (datacenterId << datacenterIdShift) |
                (workerId << workerIdShift) |
                sequence;
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }

    public static void main(String[] args) {
        IdWorker idWorker = new IdWorker(0, 0);
        for (int i = 0; i < 100; i++) {
            System.out.println(idWorker.nextId());
        }
    }
}

四、結論

總的來說,Java UUID的理論唯一性是較高的,但在實際應用中仍需要考慮UUID重複的情況。針對不同的情況,我們可以採用不同的解決方案,比如使用ThreadLocalRandom類、第三方UUID生成器、自定義演算法等。在使用的時候,一定要根據實際情況進行選擇並進行合理的使用和調整,以保證系統的性能和穩定性。

原創文章,作者:YCLV,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/134710.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
YCLV的頭像YCLV
上一篇 2024-10-04 00:07
下一篇 2024-10-04 00:07

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論