📜  java 唯一 ID - Java (1)

📅  最后修改于: 2023-12-03 14:42:18.073000             🧑  作者: Mango

Java唯一ID - Java

在Java中,唯一ID(Unique ID)是一个在系统中用于标识对象的唯一标识符。

UUID

UUID(Universally Unique Identifier)是Java中的一种唯一ID生成器。它可以生成一个128位长的通用唯一标识符。

import java.util.UUID;

public class TestUUID {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println("UUID: " + uuid.toString());
    }
}

输出:

UUID: e4a5f917-6657-4fbf-bb23-46d8f2e849ba
snowflake算法

snowflake算法是Twitter开源的一种ID生成算法。它可以生成一个64位长的ID,其中包括了时间戳、机器ID、序列号等信息,保证了生成的ID全局唯一。

public class IdWorker {
    private static final long twepoch = 1514736000000L;
    private static final long workerIdBits = 5L;
    private static final long datacenterIdBits = 5L;
    private static final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private static final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    private static final long sequenceBits = 12L;
    private static final long workerIdShift = sequenceBits;
    private static final long datacenterIdShift = sequenceBits + workerIdBits;
    private static final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    private static final long sequenceMask = -1L ^ (-1L << sequenceBits);

    private long workerId;
    private long datacenterId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;

    public IdWorker(long workerId, long datacenterId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException(
                    String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
                    lastTimestamp - timestamp));
        }
        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 class TestIdWorker {
    public static void main(String[] args) {
        IdWorker idWorker = new IdWorker(1, 1);
        long id = idWorker.nextId();
        System.out.println("ID: " + id);
    }
}

输出:

ID: 304793647814801153
总结

Java中有多种生成唯一ID的方式。选择一个合适的唯一ID生成算法可以为系统的稳定性和可伸缩性提供保障。