| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- package com.zsElectric.boot.common.util;
- import lombok.Getter;
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
- import java.util.concurrent.atomic.AtomicInteger;
- /**
- * 基于时间戳的4位自增序列和时间戳生成器
- * 规则:同一秒内序列号自增(0001-9999),下一秒序列重置为0001
- *
- * @author: wzq
- * @date: 2025/11/12
- */
- public class SequenceGenUtil {
- private static final AtomicInteger currentSequence = new AtomicInteger(0);
- private static volatile long lastSecond = -1L;
- private static final int MAX_SEQUENCE = 9999;
- // 时间格式化器(线程安全)
- private static final DateTimeFormatter TIMESTAMP_FORMATTER =
- DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
- /**
- * 序列号生成结果对象
- */
- @Getter
- public static class SequenceResult {
- private final String sequence; // 4位序列号,如 "0001"
- private final String timestamp; // 时间戳,如 "20251112154530"
- public SequenceResult(String sequence, String timestamp) {
- this.sequence = sequence;
- this.timestamp = timestamp;
- }
- /**
- * 获取完整编号:时间戳 + 序列号
- */
- public String getFullNumber() {
- return timestamp + sequence;
- }
- @Override
- public String toString() {
- return "SequenceResult{sequence='" + sequence + "', timestamp='" + timestamp + "'}";
- }
- }
- /**
- * 生成序列号和时间戳
- * 使用synchronized确保线程安全
- */
- public static synchronized SequenceResult generate() {
- long currentSecond = getCurrentSecond();
- String currentTimestamp = formatTimestamp(currentSecond);
- // 检查是否是新的一秒
- if (currentSecond != lastSecond) {
- currentSequence.set(0);
- lastSecond = currentSecond;
- }
- // 获取下一个序列值
- int seq = currentSequence.incrementAndGet();
- // 检查序列号是否溢出
- if (seq > MAX_SEQUENCE) {
- waitForNextSecond(currentSecond);
- // 递归调用,进入新秒后重新生成
- return generate();
- }
- // 格式化为4位数字并返回结果对象
- String sequenceStr = String.format("%04d", seq);
- return new SequenceResult(sequenceStr, currentTimestamp);
- }
- /**
- * 仅生成4位序列号(保持原有功能)
- */
- public static synchronized String generateSequenceOnly() {
- return generate().getSequence();
- }
- /**
- * 生成完整编号(时间戳+序列号)
- */
- public static synchronized String generateFullNumber() {
- return generate().getFullNumber();
- }
- /**
- * 获取当前时间的秒级时间戳
- */
- private static long getCurrentSecond() {
- return System.currentTimeMillis() / 1000;
- }
- /**
- * 将秒级时间戳格式化为 yyyyMMddHHmmss
- */
- private static String formatTimestamp(long timestampInSeconds) {
- LocalDateTime dateTime = LocalDateTime.ofEpochSecond(timestampInSeconds, 0,
- java.time.ZoneOffset.UTC);
- // 调整时区为系统默认时区
- return dateTime.atZone(java.time.ZoneId.systemDefault()).format(TIMESTAMP_FORMATTER);
- }
- /**
- * 等待下一秒(当序列号溢出时调用)
- */
- private static void waitForNextSecond(long currentSecond) {
- while (getCurrentSecond() <= currentSecond) {
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException("序列生成器等待被中断", e);
- }
- }
- }
- /**
- * 重置生成器状态(主要用于测试)
- */
- public static synchronized void reset() {
- lastSecond = -1L;
- currentSequence.set(0);
- }
- public static void main(String[] args) {
- System.out.println("=== 生成序列号和时间戳 ===");
- // 生成完整的序列结果(包含序列号和时间戳)
- SequenceGenUtil.SequenceResult result1 = SequenceGenUtil.generate();
- System.out.println("序列号: " + result1.getSequence()); // 输出: 0001
- System.out.println("时间戳: " + result1.getTimestamp()); // 输出: 20251112154530
- System.out.println("完整编号: " + result1.getFullNumber()); // 输出: 202511121545300001
- System.out.println("完整对象: " + result1.toString());
- // 同一秒内连续生成
- System.out.println("\n=== 同一秒内连续生成 ===");
- for (int i = 0; i < 3; i++) {
- SequenceGenUtil.SequenceResult result = SequenceGenUtil.generate();
- System.out.println("时间戳: " + result.getTimestamp() + ", 序列号: " + result.getSequence());
- }
- // 仅生成序列号(保持原有功能)
- System.out.println("\n=== 仅生成序列号 ===");
- String sequenceOnly = SequenceGenUtil.generateSequenceOnly();
- System.out.println("仅序列号: " + sequenceOnly);
- // 生成完整编号
- System.out.println("\n=== 生成完整编号 ===");
- String fullNumber = SequenceGenUtil.generateFullNumber();
- System.out.println("完整编号: " + fullNumber);
- // 模拟跨秒生成
- System.out.println("\n=== 模拟跨秒生成 ===");
- SequenceGenUtil.SequenceResult beforeSleep = SequenceGenUtil.generate();
- System.out.println("休眠前: " + beforeSleep.getTimestamp() + " - " + beforeSleep.getSequence());
- try {
- Thread.sleep(1000); // 等待1秒
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- SequenceGenUtil.SequenceResult afterSleep = SequenceGenUtil.generate();
- System.out.println("休眠后: " + afterSleep.getTimestamp() + " - " + afterSleep.getSequence());
- }
- }
|