スノーフレークは、固有のIDアルゴリズムを雪

スノーフレークパッケージ; 

/ ** 
 * 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)。
        } 
    } 
}

  

おすすめ

転載: www.cnblogs.com/codigup/p/11307269.html