@Test public void testMultithreadGenerator() { final int numSequenceBits = 12; final int numWorkerBits = 12; final IdGenerator worker = new IdGenerator(1, numWorkerBits, numSequenceBits); final int numThreads = 10; final int numRunnables = 20; final int numLoops = (int) (Math.pow(2, numSequenceBits) * 10); final List<long[]> ids = new ArrayList<long[]>(); for (int i = 0; i < numRunnables; i++) { ids.add(new long[numLoops]); } final CountDownLatch startLatch = new CountDownLatch(numThreads); final CountDownLatch doneLatch = new CountDownLatch(numRunnables); ExecutorService executor = Executors.newFixedThreadPool(numThreads); for (int i = 0; i < numRunnables; i++) { final long[] loopData = ids.get(i); Runnable r = new Runnable() { public void run() { startLatch.countDown(); try { startLatch.await(); } catch (InterruptedException ie) { throw new RuntimeException(ie); } for (int j = 0; j < numLoops; j++) { loopData[j] = worker.getNextId(); } doneLatch.countDown(); } }; executor.execute(r); } try { doneLatch.await(); } catch (InterruptedException ie) { throw new RuntimeException(ie); } executor.shutdown(); Set<Long> allids = new HashSet<Long>(); for (int i = 0; i < ids.size(); i++) { for (Long id : ids.get(i)) { assertFalse("index [" + i + "] not set earlier (" + id.longValue() + ")", allids.contains(id.longValue())); allids.add(id.longValue()); } } }
public long getNextId() { synchronized (syncObject) { long timestamp = timeProvider.getTimeInMillis(); if (prevTimestamp < timestamp) { sequence = 0L; prevTimestamp = timestamp; return buildKey(timestamp, workerId, sequence); } timestamp = prevTimestamp; sequence = ((sequence + 1) & sequenceBitMask); if (0L == sequence) { timestamp++; log.info("Cheating, advancing timestamp by 1ms. workerId = " + workerId); prevTimestamp = timestamp; } return buildKey(timestamp, workerId, sequence); } }
IdGenerator { public long getNextId() { synchronized (syncObject) { long timestamp = timeProvider.getTimeInMillis(); if (prevTimestamp < timestamp) { sequence = 0L; prevTimestamp = timestamp; return buildKey(timestamp, workerId, sequence); } timestamp = prevTimestamp; sequence = ((sequence + 1) & sequenceBitMask); if (0L == sequence) { timestamp++; log.info("Cheating, advancing timestamp by 1ms. workerId = " + workerId); prevTimestamp = timestamp; } return buildKey(timestamp, workerId, sequence); } } }
IdGenerator { public long getNextId() { synchronized (syncObject) { long timestamp = timeProvider.getTimeInMillis(); if (prevTimestamp < timestamp) { sequence = 0L; prevTimestamp = timestamp; return buildKey(timestamp, workerId, sequence); } timestamp = prevTimestamp; sequence = ((sequence + 1) & sequenceBitMask); if (0L == sequence) { timestamp++; log.info("Cheating, advancing timestamp by 1ms. workerId = " + workerId); prevTimestamp = timestamp; } return buildKey(timestamp, workerId, sequence); } } IdGenerator(final long workerId);  IdGenerator(final long workerId, final TimeProvider timeProvider);  IdGenerator(final long workerId, final int numBitsWorkerId, final int numBitsSequence);  IdGenerator(final long workerId, final TimeProvider timeProvider,
                       final int numBitsWorkerId, final int numBitsSequence); }
IdGenerator { public long getNextId() { synchronized (syncObject) { long timestamp = timeProvider.getTimeInMillis(); if (prevTimestamp < timestamp) { sequence = 0L; prevTimestamp = timestamp; return buildKey(timestamp, workerId, sequence); } timestamp = prevTimestamp; sequence = ((sequence + 1) & sequenceBitMask); if (0L == sequence) { timestamp++; log.info("Cheating, advancing timestamp by 1ms. workerId = " + workerId); prevTimestamp = timestamp; } return buildKey(timestamp, workerId, sequence); } } IdGenerator(final long workerId);  IdGenerator(final long workerId, final TimeProvider timeProvider);  IdGenerator(final long workerId, final int numBitsWorkerId, final int numBitsSequence);  IdGenerator(final long workerId, final TimeProvider timeProvider,
                       final int numBitsWorkerId, final int numBitsSequence); long getNextId(); String getNextIdHex(); long getWorkerId(); }
IdGenerator { public long getNextId() { synchronized (syncObject) { long timestamp = timeProvider.getTimeInMillis(); if (prevTimestamp < timestamp) { sequence = 0L; prevTimestamp = timestamp; return buildKey(timestamp, workerId, sequence); } timestamp = prevTimestamp; sequence = ((sequence + 1) & sequenceBitMask); if (0L == sequence) { timestamp++; log.info("Cheating, advancing timestamp by 1ms. workerId = " + workerId); prevTimestamp = timestamp; } return buildKey(timestamp, workerId, sequence); } } IdGenerator(final long workerId);  IdGenerator(final long workerId, final TimeProvider timeProvider);  IdGenerator(final long workerId, final int numBitsWorkerId, final int numBitsSequence);  IdGenerator(final long workerId, final TimeProvider timeProvider,
                       final int numBitsWorkerId, final int numBitsSequence); long getNextId(); String getNextIdHex(); long getWorkerId();  }