admin管理员组

文章数量:1794759

生成19位bigint/long类型的不重复id

生成19位bigint/long类型的不重复id

项目中经常会用到id,一个项目中偶尔会使用到全局id,要求不重复且具有一定的查询效率,所以写了一个19位的不重复id生成器


public class IdWorker { /** * 一启动就创建一个worker,如果有多台机器,则workerID和datacenterID可以从配置文件中读取 */ private static IdWorker worker = new IdWorker(1, 1, 1); /** * 生成一个ID * * @return */ public static long getId() { return worker.nextId(); } private long workerId; private long datacenterId; private long sequence; private IdWorker(long workerId, long datacenterId, long sequence) { 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)); } System.out.printf( "worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d \\r\\n", timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); this.workerId = workerId; this.datacenterId = datacenterId; this.sequence = sequence; } private long twepoch = 1288834974657L; private long workerIdBits = 5L; private long datacenterIdBits = 5L; private long maxWorkerId = -1L ^ (-1L << workerIdBits); private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); private long sequenceBits = 12L; private long workerIdShift = sequenceBits; private long datacenterIdShift = sequenceBits + workerIdBits; private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; private long sequenceMask = -1L ^ (-1L << sequenceBits); private long lastTimestamp = -1L; private synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp); throw new RuntimeException(String.format( "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0; } lastTimestamp = timestamp; return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; } private long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } private long timeGen() { return System.currentTimeMillis(); } static Map<Long, Long> kvs = Collections.synchronizedMap(new HashMap<Long, Long>()); // ---------------测试--------------- public static void main(String[] args) { for (int i = 0; i < 10; i++) { Thread t = new Thread(new Runnable() { public void run() { // System.out.println( Thread.currentThread().getId()); for (int i = 0; i < 1000; i++) { long id = IdWorker.getId(); System.out.println(id); if (!kvs.containsKey(id)) { kvs.put(id, id); // System.out.println(id); } else { System.out.println("重复的ID:" + id); } try { Thread.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); t.start(); } } }

 

本文标签: 类型bigintidlong