スノーフレークパッケージ; / ** * Twitter_Snowflake <BR> (各セクションと-間隔)*スノーフレーク、以下の構造:<BR> * 0から0 0000000000 0000000000 0000000000 0000000000 - 0000000000から000000000000 <BR> *ビット識別子1、以来。基本型はJavaで長い署名され、最上位ビットは符号ビットであり、0は正の数、負の数は1であるので、idが最上位ビットが0 <BR>され、通常は正の数、である * 41ビット時間(ミリ秒)を切り捨てられ、注意を、41カットオフ時間は、電流遮断時に記憶された時間ではなく、カットオフの蓄積時間との差- (カットオフ現在時刻開始時刻カット) 値が得られる*)、切り捨てられ、一般的に我々のID発生器の開始時間時間は、私たち(以下、次の手順IdWorkerのstartTime属性クラス)で指定されたプログラムを開始しました。カットオフ時間41は、69 = T(1L << 41である)/(* 24 * 365 1000L * 60 * 60)= 69 <BR>で、で使用することができる * 10ビットデータ・ビット・マシン1024に配備することができます5 datacenterId <BR> 5 workerId含むノード、および ミリ秒以内* 12の配列数、ID番号4096を生成するために、ミリ秒あたりの各サポートノードの配列番号12(同じマシン、同じカットオフ時間)のカウント<BR > *ロングタイプのためだけで64まで追加。<BR> * / SnowflakeIdWorkerTestクラス{公共 //フィールド============= ============================== ============================== / **時間カット(2015年1月1日)* /スタート 民間最終ロングtwepochを= 1420041600000L; 中央値/マシンIDを共有** * / 最終ロングworkerIdBits = 5Lプライベート; / **桁識別するID共有データ* / 民間最終ロングdatacenterIdBits = 5L; / **サポートされる最大マシンID、図31は、* /(迅速に進進数の最大数を計算することができ、この変位アルゴリズムは、いくつかの表すことができる)の結果である 、プライベートロングmaxWorkerId最終-1L = ^(-1L << workerIdBits) 最大/サポート**識別データID、結果は、/ * 31である プライベートロングmaxDatacenterId最終-1L = ^(-1L << datacenterIdBits); メジアンID * /表現/ **配列 プライベートロングsequenceBitsファイナル= 12Lと、 /マシンID **左12 * / 最終workerIdShift = sequenceBitsロングプライベート; / ** ID識別データ17(12 + 5)* /左に プライベートロングdatacenterIdShift =最終sequenceBits + workerIdBits、 左22をカットする/ **時間(5 + 5 + 12 )* / プライベートロングtimestampLeftShift =最終workerIdBitsのsequenceBits + + datacenterIdBits; / **マスクシーケンスを生成し、ここでは4095(0b111111111111 = 0xFFF = 4095)* / プライベートロングsequenceMask決勝-1L = ^(-1L << sequenceBits) ; / *作業機ID(〜31である0)* / プライベートロングworkerId; / *データセンターのID(〜31である0)* / プライベートロングdatacenterId; / **ミリ秒シーケンス(0〜4095)* / ロングプライベート= 0Lシーケンス; / **以前に生成されたID断時間* / プライベートロングLastTimestamp = -1L; // ==============================コンストラクタ================= ==================== / ** *构造函数 * @param workerId工作ID(0〜31) * @param datacenterId数据中心ID(0〜31) * / パブリックSnowflakeIdWorkerTest(長いworkerId、長いdatacenterId){ IF(workerId> maxWorkerId || workerId <0){ 新をスロー(String.Formatの( "作業者Idは%dまたは0より小さい値を超えることはできません"、maxWorkerId) ); } IF(datacenterId> maxDatacenterId || datacenterId <0){ 新しいはIllegalArgumentException(String.Formatの( "データセンターIDが%dまたは0より小さい値を超えることはできません" maxDatacenterId))を投げます。 } この。 this.datacenterId = datacenterId; } //メソッド==== ============================== ====================================== / ** *である(IDで得られましたスレッドセーフ) * @return SnowflakeId * / パブリックNEXTID同期ロング(){ ロングTIMEGENタイムスタンプ=(); //現在の時間は、システムクロックバックオフ時間を示す、最後の世代のIDのタイムスタンプよりも小さい場合はを通じてスローされるべきです (タイムスタンプ<LastTimestamp)IF { のRuntimeException新しい新しい投げる( String.Formatの(LastTimestamp -タイムスタンプ)「クロックは、%Dミリ秒を生成することを拒否するための下位IDを動かし。」); } //それが同時に発生した場合、それはミリ秒以内に行われますシーケンス IF(LastTimestamp ==タイムスタンプ){ シーケンス=(+配列1)&sequenceMask; //ミリ秒シーケンスオーバーフロー IF(配列== 0){ //次ミリ秒ブロッキング、新しいタイムスタンプ取得 スタンプ= tilNextMillis(lastTimestampを); } } //変更タイム・スタンプ、シーケンスミリ秒リセット 他{ シーケンス= 0Lを; } // IDは、時間の最後のカット発生 LastTimestamp =タイムスタンプ; //論理和組成物64と戦うためにシフトIDの リターン((タイムスタンプ- twepoch)<< timestampLeftShift)// |(datacenterId << datacenterIdShift)// |(workerId << workerIdShift)// |配列; } / ** *次ミリ秒に閉塞、新しいタイムスタンプまで / ** *テスト/ * @param lastTimestamp時間切る前に生成されたID * @return現在のタイムスタンプ * / 保護ロングtilNextMillis(ロングLastTimestamp){ ロングTIMEGENタイムスタンプ=(); 一方、(タイムスタンプ<= LastTimestamp){ タイムスタンプTIMEGEN =(); } 戻り値のタイムスタンプは; } / ** *ミリ秒単位で現在の時刻を返します * @ (MS)は、現在の時刻を戻す * / ロングTIMEGEN(保護){ (のSystem.currentTimeMillisを返す); } // ========================== ====テスト============================================= SnowflakeIdWorkerTest idWorker新しい新しいSnowflakeIdWorkerTestは=(0、0); のために(INT I = 0、I 1000 <; Iは++){ パブリック静的無効メイン(文字列[] args){ 長いID = idWorker.nextId()。 System.out.println(Long.toBinaryString(ID))。 System.out.println(ID)。 } } }