パッケージcom.gildata.task.platform.common.util; import java.net.Inet4Address; import java.net.UnknownHostException; import java.util.HashSet; import java.util.Random; import java.util.Set; / * * * @className:SnowflakeUtils * @description:TODO * @author: * @date:2020-11-04 13:33 * / public class SnowflakeUtils { / **時間部分の長さ* / private static final int TIME_LEN = 41; / **データセンターIDの長さ* / private static final int DATA_LEN = 5; / **マシンIDの長さ* / private static final int WORK_LEN = 5; / **シーケンスの長さ(ミリ秒)* / private static final int SEQ_LEN = 12; / **開始時刻を定義します2015-01-0100 :00:00 * / private static final long START_TIME = 1420041600000L; / **最後のID生成タイムカット* / private static long LAST_TIME_STAMP = -1L; / **数値タイムパート22で左に移動したビット数* / private static final int TIME_LEFT_BIT = 64-1-TIME_LEN; / **データセンターIDを自動的に取得します(0〜31の数値を手動で定義できます)* / private static final long DATA_ID = getDataId(); / **自動マシンID(0〜31の数値を手動で定義できます)* / private static final long WORK_ID = getWorkId(); / **最大データセンターID31 * / private static final int DATA_MAX_NUM =〜(-1 << DATA_LEN); / **最大マシン ID31 * / private static final int WORK_MAX_NUM =〜(-1 << WORK_LEN); / **データセンターIDパラメーター32をランダムに取得* / private static final int DATA_RANDOM = DATA_MAX_NUM + 1; / **マシンIDパラメーターへのランダムアクセス32 * / private static final int WORK_RANDOM = WORK_MAX_NUM + 1; / **データセンターID左シフト番号17 * / private static final int DATA_LEFT_BIT = TIME_LEFT_BIT-DATA_LEN; / **マシンID左シフト番号12 * / private static final int WORK_LEFT_BIT = DATA_LEFT_BIT-WORK_LEN; / **最後のタイムシーケンス値(ミリ秒)* / private static long LAST_SEQ = 0L; / **ミリ秒最大値内部シーケンスのは4095です* / private static final long SEQ_MAX_NUM =〜(-1 << SEQ_LEN); public synchronized static long genId(){ long now = System.currentTimeMillis(); //現在の時刻が以下の場合最後のID生成タイムスタンプ。この時間の後にシステムクロックが例外をスローする必要があることを示します。 if(now <LAST_TIME_STAMP){ throw new RuntimeException(String.format( "システム時間エラー!%dミリ秒以内にスノーフレークIDを生成することを拒否しました!"、START_TIME-now)); } if(now == LAST_TIME_STAMP){ LAST_SEQ =(LAST_SEQ + 1)&SEQ_MAX_NUM; if(LAST_SEQ == 0){ now = nextMillis(LAST_TIME_STAMP); } } else { LAST_SEQ = 0; } // IDが最後に生成された 時刻LAST_TIME_STAMP = now; return((now-START_TIME)<< TIME_LEFT_BIT)| (DATA_ID << DATA_LEFT_BIT)|(WORK_ID << WORK_LEFT_BIT)| LAST_SEQ; } / ** *最後のタイムスタンプと同じではなく、次の異なるミリ秒のタイムスタンプを取得します * / public static long nextMillis(long lastMillis){ * // long now = System.currentTimeMillis(); while(now <= lastMillis){ now = System.currentTimeMillis(); } return now; } / ** *文字列sのバイト配列を取得し、配列の要素を追加します、(max + 1)の残りを取り ます * / private static int getHostId(String s、int max){ byte [] bytes = s.getBytes(); int sums = 0; for(int b:bytes){ sums + = b; } return sums%(max + 1); } / ** *ホストアドレスに従って残りを取得し、例外が発生したときにランダムな数値を取得します try { public static int getWorkId(){ return getHostId(Inet4Address.getLocalHost()。getHostAddress()、WORK_MAX_NUM); } catch(UnknownHostException e){ return new Random()。nextInt(WORK_RANDOM); } } / ** *根被ホスト名取余、ρ生异常就获取0到31之幅的随机数 * / public static int getDataId(){ try { return getHostId(Inet4Address.getLocalHost()。getHostName()、DATA_MAX_NUM) ; } catch(UnknownHostException e){ return new Random()。nextInt(DATA_RANDOM); } } public static void main(String [] args){ Set ids = new HashSet(); long start = System.currentTimeMillis(); for(int i = 0; i <3000000; i ++){ ids.add(genId()); } long end = System.currentTimeMillis(); System.out.println( "合計生成ID [" + ids.size( )+ "]、費やした時間[" +(終了-開始)+ "]ミリ秒"); } }
Java--スノーフレークアルゴリズム
おすすめ
転載: blog.csdn.net/CUITAO2305532402/article/details/112134899
ランキング