@Service public class RedisSequenceFactory { @Autowired RedisTemplate<String, String> redisTemplate;
public void setSeq(String key, int value, Date expireTime) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); counter.set(value); counter.expireAt(expireTime); }
public void setSeq(String key, int value, long timeout, TimeUnit unit) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); counter.set(value); counter.expire(timeout, unit); }
public long generate(String key) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); return counter.incrementAndGet(); }
public long incr(String key, Date expireTime) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); counter.expireAt(expireTime); return counter.incrementAndGet(); }
public long incr(String key, int increment) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); return counter.addAndGet(increment); }
public long incr(String key, int increment, Date expireTime) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); counter.expireAt(expireTime); return counter.addAndGet(increment); } }
/** * 雪花算法 * @author:黎杜 */ public class SnowflakeIdWorker {
/** 开始时间截 */ private final long twepoch = 1530051700000L;
/** 机器id的位数 */ private final long workerIdBits = 5L;
/** 数据标识id的位数 */ private final long datacenterIdBits = 5L;
/** 最大的机器id,结果是31 */ private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
/** 最大的数据标识id,结果是31 */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
/** 序列的位数 */ private final long sequenceBits = 12L;
/** 机器ID向左移12位 */ private final long workerIdShift = sequenceBits;
/** 数据标识id向左移17位 */ private final long datacenterIdShift = sequenceBits + workerIdBits;
/** 时间截向左移22位*/ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
/** 生成序列的掩码 */ private final long sequenceMask = -1L ^ (-1L << sequenceBits);
/** 工作机器ID(0~31) */ private long workerId;
/** 数据中心ID(0~31) */ private long datacenterId;
/** 毫秒内序列(0~4095) */ private long sequence = 0L;
/** 上次生成ID的时间截 */ private long lastTimestamp = -1L;
/** * 构造函数 * @param workerId 工作ID (0~31) * @param datacenterId 数据中心ID (0~31) */ public SnowflakeIdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; }
/** * 获得下一个ID (该方法是线程安全的) * @return SnowflakeId */ public synchronized long nextId() { long timestamp = getCurrentTime();
//如果当前时间小于上一次生成的时间戳,说明系统时钟回退过就抛出异常 if (timestamp < lastTimestamp) { throw new BusinessionException("回拨的时间为:"+lastTimestamp - timestamp); }