All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.sylphlike.framework.utils.sequence.GeneSequence Maven / Gradle / Ivy

The newest version!
package com.github.sylphlike.framework.utils.sequence;

import com.github.sylphlike.framework.utils.general.Clock;

import java.util.concurrent.ThreadLocalRandom;

/**
 * 

time 23/09/2020 09:10 星期三 (dd/MM/YYYY HH:mm) *

email [email protected] * * @author Gopal.pan * @version 1.0.0 */ public class GeneSequence { /** 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)*/ private final static long TWEPOCH = 1585038908558L; /** 数据中心标识位数 */ private final static long DATA_CENTER_ID_BITS = 4L; /** 机器标识位数 */ private final static long WORKER_ID_BITS = 4L; /** 毫秒内自增位 */ private final static long SEQUENCE_BITS = 10L; /** 基因自增位 */ private final static long GENE_BITS = 4L; /** 机器ID最大值 */ private final static long MAX_WORKER_ID = 14; /** 数据中心ID最大值 */ private final static long MAX_DATA_CENTER_ID = 14; /** 序列左移4位 */ private final static long SEQUENCE_ID_SHIFT = GENE_BITS; /** 机器ID偏左移12位 */ private final static long WORKER_ID_SHIFT = SEQUENCE_ID_SHIFT + SEQUENCE_BITS; /** 数据中心ID左移17位 */ private final static long DATA_CENTER_ID_SHIFT = WORKER_ID_SHIFT + WORKER_ID_BITS; /** 时间毫秒左移22位 */ private final static long TIMESTAMP_LEFT_SHIFT = DATA_CENTER_ID_SHIFT +DATA_CENTER_ID_BITS; private final static long SEQUENCE_MASK = 1023; /** 上次生产id时间戳 */ private static long lastTimestamp = -1L; /** 并发控制 */ private long sequence = 0L; /** 分库分表大小 */ private final static long GENE_SIZE = 16; private final long dataCenterId; private final long workerId; public GeneSequence() { this.dataCenterId = MarkProvider.getDataCenterId(MAX_DATA_CENTER_ID); this.workerId = MarkProvider.getWorkerId(dataCenterId, MAX_WORKER_ID); } public GeneSequence(long workerId, long dataCenterId) { if (workerId > MAX_WORKER_ID || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID)); } if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) { throw new IllegalArgumentException(String.format("dataCenter Id can't be greater than %d or less than 0", MAX_DATA_CENTER_ID)); } this.workerId = workerId; this.dataCenterId = dataCenterId; } /** * 获取下一个ID *

time 10:49 2021/1/5 (HH:mm yyyy/MM/dd) *

email [email protected] * @param orgId 原始ID * @return long * @author Gopal.pan */ public synchronized long nextId(Long orgId) { long timestamp = Clock.now(); timeMillisGen(timestamp); // 41位时间截(毫秒级) << 22 | 4位的数据机器位 << 16 | 4位workerId << 14 | 8位序列 << 4 | 4为基因序列 return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | (dataCenterId << DATA_CENTER_ID_SHIFT) | (workerId << WORKER_ID_SHIFT) | sequence << SEQUENCE_ID_SHIFT | orgId % GENE_SIZE; } private long tilNextMillis(final long lastTimestamp) { long timestamp = Clock.now(); while (timestamp <= lastTimestamp) { timestamp = Clock.now(); } return timestamp; } private void timeMillisGen(long timestamp) { if (timestamp < lastTimestamp) { throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { // 当前毫秒内,则+1 sequence = (sequence + 1) & SEQUENCE_MASK; if (sequence == 0) { // 当前毫秒内计数满了,则等待下一秒 timestamp = tilNextMillis(lastTimestamp); } } else { sequence = ThreadLocalRandom.current().nextLong(0, GENE_SIZE); } lastTimestamp = timestamp; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy