我有一个在多线程环境中使用的Hi-lo Id生成器。每个线程每秒最多可调用10万次生成器

我有一个相当不错(和安全)的实现,效果很好。 IdAllocator是获取ID的下一个“批次”的对象。您可以假定这是线程安全的。我还将batchSize设置得很高(一百万)

private final IdAllocator idAllocator;
private final String idKey;
private final int batchSize;

private final Object lock = new Object();

private long currentId = 0;
private long nextFetchId = -1;

IdGeneratorImpl( IdAllocator idAllocator, String idKey, int batchSize )
{
    this.idAllocator = idAllocator;
    this.idKey = idKey;
    this.batchSize = batchSize;
}

public long getNextId()
{
    synchronized ( lock )
    {
        if ( currentId < nextFetchId )
        {
            long localCurrent = currentId;
            currentId++;
            return localCurrent;
        }

        currentId = idAllocator.allocateBatch( idKey, batchSize );
        nextFetchId = currentId + batchSize;

        return getNextId();
    }
}


目前,我主要(但不总是)以一种无竞争的方式使用它。但是,将来它将由多个线程调用。

我考虑过为每个线程实例化一个实例,这可能是最好的方法。但是,作为知识/学习经验,我想知道是否可以对这种实现进行改进,特别是当多个线程频繁调用getNextId()时,可以减少潜在的争用吗?

最佳答案

如果您查看Hibernate TableHiLoGenerator,它将在生成方法中使用一个简单的synchronized,这意味着多个线程将等待,因此只有一个线程一次执行该方法。您已经对lock执行了相同的操作(这有点多余-synchronized方法执行相同的操作)。因此,我认为您的实现很好。

关于java - 高低ID发生器的改进,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3444459/

10-13 07:00