@Override public void run() { for (int i = 0; i != 100000; ++i) { counter.nextKey(); } } }).run();
/** * Get the next key for the current time in UTC. * * @return a long that is determined by the current time in UTC and a unique counter value for the current time. */ public long nextKey() { // Note that per Oracle the currentTimeMillis is the current number of seconds past the epoch // in UTC (not in local time). Therefore, processes with exactly synchronized clocks will // always get the same value regardless of their timezone ... final long timestamp = System.currentTimeMillis(); final int increment = counterFor(timestamp); if (increment <= maximumCounterValue) { return (timestamp << counterBits) + increment; } // The counter is surprisingly too high, so try again (repeatedly) until we get to the next millisecond ... return this.nextKey(); }
/** * Get the next key for the current time in UTC. * * @return a long that is determined by the current time in UTC and a unique counter value for the current time. */ public long nextKey() { // Note that per Oracle the currentTimeMillis is the current number of seconds past the epoch // in UTC (not in local time). Therefore, processes with exactly synchronized clocks will // always get the same value regardless of their timezone ... final long timestamp = System.currentTimeMillis(); final int increment = counterFor(timestamp); if (increment <= maximumCounterValue) { return (timestamp << counterBits) + increment; } // The counter is surprisingly too high, so try again (repeatedly) until we get to the next millisecond ... return this.nextKey(); }
/** * Get the next key for the current time in UTC. * * @return a long that is determined by the current time in UTC and a unique counter value for the current time. */ public long nextKey() { // Note that per Oracle the currentTimeMillis is the current number of seconds past the epoch // in UTC (not in local time). Therefore, processes with exactly synchronized clocks will // always get the same value regardless of their timezone ... final long timestamp = System.currentTimeMillis(); final int increment = counterFor(timestamp); if (increment <= maximumCounterValue) { return (timestamp << counterBits) + increment; } // The counter is surprisingly too high, so try again (repeatedly) until we get to the next millisecond ... return this.nextKey(); }
@Test public void shouldObtain10MillionCountersFromThreadSafeUsingMultipleThreads() { print(counter.nextKey()); for (int j = 0; j != 100; ++j) { new Thread(new Runnable() { @Override public void run() { for (int i = 0; i != 100000; ++i) { counter.nextKey(); } } }).run(); } print(counter.nextKey()); }
@Override public synchronized void addRecords( JournalRecord... records ) { if (stopped) { return; } LOGGER.debug("Adding {0} records", records.length); for (JournalRecord record : records) { if (record.getTimeBasedKey() < 0) { //generate a unique timestamp only if there isn't one. In some scenarios (i.e. running in a cluster) we //always want to keep the original TS because otherwise it would be impossible to have a correct order //and therefore search long createTimeMillisUTC = TIME_BASED_KEYS.nextKey(); record.withTimeBasedKey(createTimeMillisUTC); } this.records.put(record.getTimeBasedKey(), record); } this.journalDB.commit(); }
@Override public synchronized void addRecords( JournalRecord... records ) { if (stopped) { return; } LOGGER.debug("Adding {0} records", records.length); for (JournalRecord record : records) { if (record.getTimeBasedKey() < 0) { //generate a unique timestamp only if there isn't one. In some scenarios (i.e. running in a cluster) we //always want to keep the original TS because otherwise it would be impossible to have a correct order //and therefore search long createTimeMillisUTC = TIME_BASED_KEYS.nextKey(); record.withTimeBasedKey(createTimeMillisUTC); } this.records.put(record.getTimeBasedKey(), record); } this.journalDB.commit(); }