UUID生成帮助类、UUID工具类

数据库主键id使用自动增长的坏处
1. 程序后台添加测试
2. 旧数据导入
3. 数据库迁移
4. 缓存 (如,两个库中id都为2时,缓存的时候会覆盖)以下为代码块
结论:一般在实际生产环境中,一般用程序来确保id的唯一性。
以下为UUID的生成工具类:


package com.cnksi.utils;

import java.net.InetAddress;

/**
 * 在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,
 * 实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位+机器ID 10位+毫秒内序列12位。
 * 该项目地址为:https://github.com/twitter/snowflake是用Scala实现的。
 * python版详见开源项目https://github.com/erans/pysnowflake。
 *
 * @author xiqiao
 * @Date 2017-12-19
 */
public class IdWorker {
    //根据具体机器环境提供
    private final long workerId;
    //滤波器,使时间变小,生成的总位数变小,一旦确定不能变动
    private final static long twepoch = 1361753741828L;
    private long sequence = 0L;
    private final static long workerIdBits = 10L;
    private final static long maxWorkerId = -1L ^ -1L << workerIdBits;
    private final static long sequenceBits = 12L;

    private final static long workerIdShift = sequenceBits;
    private final static long timestampLeftShift = sequenceBits + workerIdBits;
    private final static long sequenceMask = -1L ^ -1L << sequenceBits;

    private long lastTimestamp = -1L;
    //根据主机id获取机器码
    private static IdWorker worker = new IdWorker();

    /**
     * 创建 IdWorker对象.
     *
     * @param workerId
     * @Deprecated 请调用静态方法getId()
     */
    @Deprecated
    public IdWorker(final long workerId) {
        if (workerId > IdWorker.maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",
                    IdWorker.maxWorkerId));
        }
        this.workerId = workerId;
    }

    public IdWorker() {
        this.workerId = getAddress() % (IdWorker.maxWorkerId + 1);
    }

    public static long getId() {
        return worker.nextId();
    }

    public synchronized long nextId() {
        long timestamp = this.timeGen();
        if (this.lastTimestamp == timestamp) {
            this.sequence = (this.sequence + 1) & IdWorker.sequenceMask;
            if (this.sequence == 0) {
                //System.out.println("###########" + sequenceMask);//等待下一毫秒
                timestamp = this.tilNextMillis(this.lastTimestamp);
            }
        } else {
            this.sequence = 0;
        }
        if (timestamp < this.lastTimestamp) {
            try {
                throw new Exception(String.format(
                        "Clock moved backwards.  Refusing to generate id for %d milliseconds", this.lastTimestamp
                                - timestamp));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        this.lastTimestamp = timestamp;
        long nextId = ((timestamp - twepoch << timestampLeftShift)) | (this.workerId << IdWorker.workerIdShift)
                | (this.sequence);
        //  System.out.println("timestamp:" + timestamp + ",timestampLeftShift:"
        //      + timestampLeftShift + ",nextId:" + nextId + ",workerId:"
        //      + workerId + ",sequence:" + sequence);
        return nextId;
    }

    private long tilNextMillis(final long lastTimestamp1) {
        long timestamp = this.timeGen();
        while (timestamp <= lastTimestamp1) {
            timestamp = this.timeGen();
        }
        return timestamp;
    }

    private static long getAddress() {
        try {
            String currentIpAddress = InetAddress.getLocalHost().getHostAddress();
            String[] str = currentIpAddress.split("\\.");
            StringBuilder hardware = new StringBuilder();
            for (int i = 0; i < str.length; i++) {
                hardware.append(str[i]);
            }
            return Long.parseLong(hardware.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return 2L;
    }

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

    public static void main(final String[] args) {
        //IdWorker worker2 = new IdWorker(0);
        //System.out.println(worker2.nextId());
        //long ll = getAddress() % 16;
        //System.out.println(ll);
        //  long start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            System.out.println(getId());
        }
        // long end = System.currentTimeMillis();
        // System.out.println((10 / (end - start)) + "个/ms");
        // System.out.println(getId());
    }

}

你可能感兴趣的:(java,帮助类,工具类)