1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| public class IdGen {
private final int len;
private final int seqBit;
private final int randomBit;
private final int workBit;
private final int workerId;
private long lastTimestamp = 0L;
private long sequence = 0L;
private static final BigInteger UNIT = new BigInteger("10");
private DateTimeFormatter FORMAT;
public IdGen(int len, int seqBit, int randomBit, int workBit , int workerId) { if ((len == 17)) { FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"); } else if ((len == 14)) { FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); } else { throw new IllegalArgumentException("时间长度只能为14或17"); }
this.workerId = workerId; this.seqBit = seqBit; this.workBit = workBit; this.randomBit = randomBit; this.len = len; int maxValue = (UNIT.pow(workBit).intValue() - 1); if (workerId > maxValue || workerId < 0) { throw new IllegalArgumentException(String.format("workerId不能大于[%d],且不能小于0", maxValue)); } }
public synchronized String nextId() { long timestamp = now();
if (timestamp < lastTimestamp) { throw new RuntimeException(String.format("时钟倒退[%s]ms", lastTimestamp - timestamp)); }
if (lastTimestamp == timestamp) { sequence = sequence + 1; if (sequence > (UNIT.pow(seqBit).intValue()-1)) { timestamp = nextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp;
int random = ThreadLocalRandom.current().nextInt(0, UNIT.pow(randomBit).intValue()); return String.format("%0"+len+"d", timestamp) + String.format("%0"+seqBit+"d", sequence) + String.format("%0"+randomBit+"d", random) + String.format("%0"+workBit+"d", workerId) ; } private long nextMillis(final long lastTimestamp) { long timestamp = this.now(); while (timestamp <= lastTimestamp) { timestamp = this.now(); } return timestamp; }
private long now() { LocalDateTime dateTime = LocalDateTime.now(); return Long.parseLong(dateTime.format(FORMAT)); }
public static void main(String[] args) { IdGen gen1 = new IdGen(17, 3, 2,2, 1); System.out.println(gen1.nextId()); IdGen gen2 = new IdGen(14, 2, 2,1, 1); System.out.println(gen2.nextId());
} }
|