【问题标题】:creating unique request id for each request using timemillis method in Servlet [duplicate]使用 Servlet 中的 timemillis 方法为每个请求创建唯一的请求 ID [重复]
【发布时间】:2016-01-05 08:45:01
【问题描述】:

我正在开发一个 servlet,我需要为每个请求提供一个唯一的请求,并将每个请求参数存储在审计表中。 如果我尝试通过查看表中的前一个 id 来增加一个值,我担心数据库表上的脏读操作。 我想知道是否在请求到达 servlet 时使用以毫秒为单位的时间来解决这个问题。 恐怕如果同一 servlet 可能同时来自其他地理位置的任何其他请求,那么 java.lang.System.currentTimeMillis() 将与其他请求相同。 让我提出这个疑问的原因是我相信 servlet 的多线程行为是一次接受一个请求,然后根据某种算法跨越每个请求的 cpu 周期。

【问题讨论】:

  • 如果你有一个同步的代码块,你获得了key,那么你可以控制它。
  • 感谢您提出有关同步块的问题,但我担心性能问题,所以只有我在想我们是否可以以毫秒为单位使用时间。您对 java.lang.System.currentTimeMillis() 值对于同一 servlet 同时到达的不同请求是唯一的有何评论。
  • 不保证以毫秒为单位的时间是唯一的。在某些操作系统上,它甚至可能以更大的块增加。
  • 感谢您对此的确认。我将尝试与 synchronized (this) { } 妥协并实现逻辑

标签: java multithreading uniqueidentifier


【解决方案1】:

System.currentTimeMillis() 在被多个线程调用时不能保证是唯一的。在过去遇到这种情况时,我使用AtomicLong 创建唯一的 id - 这个类的 getAndIncremenet 在大多数 JVM 上应该是无锁的(因此相当有效)

public class IdUtil {
    private static final AtomicLong counter = new AtomicLong(System.currentTimeMillis());

    // return a single id
    public static long getId() {
        return counter.getAndIncrement();
    }

    // return a block of ids
    public static Queue<Long> getIds(long span) {
        long max = counter.addAndGet(span);
        Queue<Long> queue = new ArrayDeque<>(span);
        for(int i = max - span; i < max; i++) {
            queue.add(i);
        }
    }
}

【讨论】:

    【解决方案2】:

    即使同步也是错误的。对于两个非常接近的请求,您可能会获得相同的 ID。您最好使用随机的长号或序列号。

    private static final Random r = new Random(); // <- shared resource
    // ...
    long id = r.nextLong();
    

    private static final AtomicLong counter = new AtomicLong(System.currentTimeMillis()); // <- shared resource
    // ...
    long id = counter.getAndIncrement();
    

    counter 以毫秒为单位进行初始化,因此在程序重启后它不会提供相同的 id 序列。

    【讨论】:

    • 有趣的是,在阅读了您的评论后,我有了一种新的方法,如果我使用上述方法,是否有可能有一天我在不同日期为两个不同的请求获得相同的 id。在这种情况下,我可以使用此 ID 和时间戳作为唯一键来识别唯一请求
    • 有 18,446,744,073,709,551,616 个不同的 long 值。 ID冲突的风险真的很低。您每天需要处理数十亿笔交易,但机会仍然很低。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    相关资源
    最近更新 更多