1. 程式人生 > >UUID生成幫助類、UUID工具類

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 = -1
L ^ -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()); } }