/ ** * Twitter_Snowflake <br> * Snowflake siguiente estructura (con cada sección - aparte): <br> * de 0 - 0 0000000000 0000000000 0000000000 0000000000 - 0000000000 - 000 mil millones <br> * identificador de bit 1, ya que los tipos básicos de largo. se firma en Java, el bit más significativo es un bit de signo, 0 es un número positivo, número negativo es 1, por lo que la identificación es por lo general un número positivo, el bit más significativo es 0 <br> * 41 hora límite (milisegundos), se señaló 41 el tiempo no es un tiempo de corte de la corriente de corte de almacenamiento tiempo, pero la diferencia entre el tiempo de almacenamiento de la línea de corte (cut-off hora actual - hora de inicio del corte) * el valor obtenido), donde el tiempo de inicio de un truncado, en general, que comenzamos con el generador de Identificación tiempo especificado por el programa (programa siguiente IdWorker horaInicio clase de atributo más adelante). Hora de corte 41, 69 se puede utilizar en, en = T (1 l << 41 es) / (1000L * 60 * 60 * 24 * 365) = 69 <br> * máquina de bits de datos de 10 bits, se puede implementar en 1024 los nodos, y que incluye 5 datacenterId <br> 5 workerId * 12 cuenta de secuencia en cuestión de milisegundos, el recuento de número de secuencia 12 de cada nodo de soporte por milisegundo (la misma máquina, el mismo corte de tiempo) para producir el número de ID 4096 <br > * ascienden a apenas 64 para un tipo Long. <br> * Ventaja del copo de nieve es que el incremento general en el orden del tiempo, y no generan colisiones ID (a diferencia de los centros de datos ID y el ID de la máquina) en todo el sistema distribuido, y alta eficiencia, a prueba, se puede generar por segundo del copo de nieve sobre 260.000 ID. * / Público clase SnowflakeIdWorker { // ============================== campos ============== ============================= / ** hora de inicio del corte (01/01/2015) * / privada final largo twepoch = 1420041600000L ; / ** proporción de dígitos de la ID de la máquina * / privadas finales largas workerIdBits = 5L ; / ** datos para identificar el número de bits ocupada por id * / privadas finales largas datacenterIdBits = 5L ; / ** el máximo soportado ID de la máquina, resultados es 31 (el algoritmo de turno puede calcular rápidamente el número máximo de número binario decimal puede representar varios) * / privada final largo maxWorkerId 1L = ^ (<< 1LworkerIdBits); / ** El máximo identificación de los datos de identificación, resultado 31 es * / privada final largo maxDatacenterId -1L = ^ (-1L << datacenterIdBits); / ** secuencia que representa el identificador de mediana * / privada final largo = sequenceBits 12L ; / ** de ID de máquina 12 a la izquierda * / privada final largo workerIdShift = sequenceBits; / ** datos de identificación ID a la dada por 17 (+ 12 es de 5.) * / privada final largo datacenterIdShift + = sequenceBits workerIdBits; / * tiempo para cortar la izquierda 22 (. + 5 + 12 es. 5) * / privada final largoworkerIdBits + + = sequenceBits timestampLeftShift datacenterIdBits; / ** generar una secuencia de máscara, aquí 4095 (0b111111111111 = 0xFFF = 4095) * / privada final largo sequenceMask 1L = ^ (1L << sequenceBits); / ** máquina de trabajo ID (~ 31 es 0) * / privada largo workerId; / ** centro de datos ID (~ 31 es 0) * / privada largo datacenterId; / ** milisegundos secuencia (0 ~ 4095) * / privada larga secuencia = 0L ; / * * última vez generada ID sección * / privada a largo LastTimestamp = 1L ; //============================== constructores =================== ================== / ** *构造函数 * @param workerId工作ID (0 ~ 31) * @param datacenterId数据中心ID (0 ~ 31) * / público SnowflakeIdWorker ( largo workerId, largo datacenterId) { si (workerId> maxWorkerId || workerId <0 ) { lanzar nuevo IllegalArgumentException (String.Format ( "trabajador Id puede no ser mayor que% d o menor que 0" , maxWorkerId)); } Si (datacenterId> maxDatacenterId || datacenterId <0 ) { de banda nueva nuevo una IllegalArgumentException (String.Format ( "no puede ser centro de datos de identificación dentro de la última Mayor% o menos than D 0" , maxDatacenterId)); } la presente .workerId = workerId; el presente .datacenterId = datacenterId; } // ================ ========================= Métodos ======================== ================== / ** * obtener el siguiente ID (que es seguro para subprocesos) * @return SnowflakeId * / pública del sincronizada largo NextID () { larga marca de tiempo = TimeGen (); // si la hora actual es menor que la fecha y hora de la última generación de identificación, indicando el tiempo de retardo de envío reloj del sistema debe ser arrojado sobre este caso(Timestamp < LastTimestamp) { de banda nueva nuevo un RuntimeException ( String.Format ( "Clock desplazado hacia atrás ID por negarse a Generar milisegundos% d.", LastTimestamp - timestamp)); } // si se genera al mismo tiempo, la secuencia se lleva a cabo en cuestión de milisegundos IF (LastTimestamp == timestamp) { secuencia = (+ secuencia 1.) y sequenceMask; // milisegundo secuencia de desbordamiento IF (secuencia == 0 ) { // el bloqueo de la siguiente milisegundo, obtener una nueva marca de tiempo timestamp = tilNextMillis (LastTimestamp ); } } //Marca de tiempo cambia, los milisegundos Reset de secuencia de la otra { Secuencia = 0L ; } // último tiempo de generación de ID sección LastTimestamp = timestamp; // cambio a la lucha y ORed juntos forman un ID de 64 bits de retorno ((timestamp - twepoch) << timestampLeftShift) // | (datacenterId << datacenterIdShift) // | (workerId << workerIdShift) // | Secuencia; } / ** * obstrucción a la siguiente milésima de segundo, hasta que un nuevo orden de llegada * @param LastTimestamp hora de la última generación de corte ID * @return la fecha y hora actual * / protegido Larga tilNextMillis ( largo LastTimestamp) { larga timestamp = TimeGen (); el tiempo (timestamp <= LastTimestamp) { timestamp = TimeGen (); } retorno marca de tiempo; } / ** * devuelve la hora actual en milisegundos * @return tiempo actual (ms) * / protegida largo TimeGen () { retorno System.currentTimeMillis (); } // ============================= ============================================= la Prueba = / ** prueba * / pública estática vacío principales (args String []) { SnowflakeIdWorker idWorker = nueva SnowflakeIdWorker (0, 0 ); para ( int i = 0; i <1,000; i ++ ) { largo id = idWorker.nextId (); System.out.println (Long.toBinaryString (id)); System.out.println (id); } } }