4

I need to generate monotonically increasing integers.

Could I use the timestamp to somehow generate such type of integer sequence?

I would request an integer at a time, and I won't be requesting more than an integer in the same second's interval - if I do, I won't mind if it passes me the same integer within that second's interval.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294

3 Answers3

4

You can use an AtomicInteger object to maintain a thread safe counter. Then use getAndIncrement() when you need the next integer.

Dev
  • 11,919
  • 3
  • 40
  • 53
1

Since monotonically increasing integers do not need to be contiguous (ie there can be gaps, as long as the number keeps increasing), and it sounds like you want all calls made in the same second to return the same integer, a method that returns how many seconds the JVM has been up would do nicely.

Here's a simple implementation that does that:

private static long startTime = System.currentTimeMillis();

public static int secondsSinceStart() {
    return (int) TimeUnit.SECONDS.convert(
        System.currentTimeMillis() - startTime, TimeUnit.MILLISECONDS);
}

FYI, this would last 68 years before rolling over.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • thanks so much @Bohemian! Inspired from suggestions from you all, I was thinking why not simply divide the milliseconds(since JVM is up) by 1000 to get the seconds `(System.currentTimeMillis()-startTime)/1000` which would then fall in integer range. And then instead of dividing by 1000, I could approximate with fast division by 1024 by bit shifting 10 bits to right. `(System.currentTimeMillis()-startTime)>>10`. Just asking for the sake of performance.. – Rajat Gupta Jan 17 '12 at 06:02
  • 1
    Actually, my code *does* just divide by 1000, but the above is the way of converting from milliseconds to seconds using the API. You could replace it with division by 1000, but I thought this looked prettier. As for performance, this method returns in about 60 nanoseconds running on my macbook - I'd say that's fast enough for most applications. – Bohemian Jan 17 '12 at 07:36
  • yes it prettier ofcourse but in terms of performance I think bit shift by 10 bits(that would result in division by 1024) would give better performance than division by 1000, perhaps !? – Rajat Gupta Jan 17 '12 at 07:40
0

This is my self made generator...

  public final class IdGenerator {

  private static final int MAGNITUDE = 10000;
  private static long previousTimestamp;

  private static int counter = 0;

  private IdGenerator() {
  }

  public synchronized static long generateId() {
    final long timeMillis = System.currentTimeMillis();
    if (previousTimestamp != timeMillis) {
      counter = 0;
    }
    previousTimestamp = timeMillis;

    final int counterValue = counter++;
    if (counterValue >= MAGNITUDE) {
      //just to be sure
      throw new IllegalStateException("too many id generated for a single timestamp!");
    }

    return timeMillis * MAGNITUDE + counterValue;
  }

}
rloeffel
  • 144
  • 7